Suppose there is a qt-object with signal. This object emits a signal which contains some object allocated on the heap (new/malloc). Event's destructor releases all allocated data. Will such data be released in any way if there is no connection to qt-object signal? If a listener closes connection before an event receiving in it's signal slot?
ADDITIONS:
Example with shortens.
class MyEvent { virtual ~MyEvent(); }; // root class for all my project events
class MyEventQueue {
MyEventQueue(); // initialize mutex
virtual ~MyEventQueue(); // delete and release all events from events_
void push_back( MyEvent *); // atomic-push event
MyEvent *pop_front(); // atomic-pop event
pthread_mutex_t sync_; // mutex for atomic operations
std::queue<MyEvent *> events_; // queue of events
};
class MyEvent1 : public MyEvent {
MyEvent1( char *);
~MyEvent1() { delete[] data; }
char *data;
};
class MyWriter {
...;
void eval();
signals: void send1( MyEventQueue *);
MyEventQueue queue_;
};
class MyReader {
...;
slots: void recv1( MyEventQueue *);
};
class MyController {
...;
}
MyWriter and MyReader are independet actors working in different threads of one process.
void MyWriter::eval() {
...;
queue_.push_back( new MyEvent1( ...));
emit send1( &queue_);
}
void MyReader::recv1( MyEventQueue *queue) {
if ( MyEvent *event = queue->pop_front() ) {
// event is delivered to MyReader
...;
delete event;
}
}
If a sended event was delivered and accepted it will be deleted in MyReader. In other way event will be kept in MyWriter::queue_.
MyController works as a dispatcher/manager for MyWriter and MyReader. Also it realizes communications with other functional blocks. At the end of the (extern) data processing cycle MyController stops MyWriter, MyReader (their threads and so on their qt-event loops). Then it closes a connection beetwen MyWriter and MyReader. If some events was sended by MyWriter, but not accepted by MyReader then allocated datas will be released in ~MyWriter() -> queue_'s destructor.
(For multiply readers I use an explicit resending in MyController with events coping or only one to one connections, in this case MyController works as a router with self event-queues.)
The main reason is pipelining and parallelization of data processing.
I doubt that possibly I duplicate qt-engine work. Of course, there may be a better solution at all.
CodePudding user response:
General recommendations about passed arguments to signal
It's up to you to destruct an objects passed as an argument of a signal. Note that multiple slots may be connected to the same signal, which may result in destructing the object multiple times.
Some (common) possibilities are:
- Pass by const reference. Qt will create a copy when a queued connection is used. Otherwise, no copy will be made.
- Pass by value. Useful for basic types, otherwise pass by const reference.
- Pass a shared pointer.
Another option may be to check whether a slot is connected to the signal, using QObject::isSignalConnected
. This function is especially useful to avoid the emission of the signal in case the arguments are resource intensive to construct. However, I do not recommend this option for your case, as it doesn't solve the case when multiple slots are connected to the same signal.
Another possibility is to implement your own callback method, which would allow you to enforce a unique callback method.