Comment 7 for bug 1406124

Revision history for this message
Daniel Schürmann (daschuer) wrote :

The issue is this
https://github.com/mixxxdj/mixxx/blob/679ffc1876ddd1f7209857cf984692a88d22bf59/src/controlobjectslave.cpp#L47
direct connection.

The calling thread, changing the co is not aware that the Slave CO is about to be deleted.

> Deleting a QObject while pending events are waiting to be delivered can cause a crash. You must not delete the QObject directly if it exists in a different thread than the one currently executing. Use deleteLater() instead, which will cause the event loop to delete the object after all pending events have been delivered to it.

I have also dig though the deleteLater() code. It just makes sure that the Object is finally deleted by the same thread that runs the event queue for it.
It does not help in this special case since the Slave CO is already deleted in the correct thread, but it may help in other cases.

What does it mean for us:
* We must not delete Slave COs form a thread that does not drive its event queue, like our engine thread, which has none.
** Every QObject has a event Queue. In case of our engine thread, it is the main queue, since it is inherited during initializing the engine. This means we have no issue here, since the engine is also deleted by the main thread.
* We must not delete a CO when we have a direct connection from a different thread. The thing becomes worse because we always have an internal direct connection.

I think the later can be fixed by putting some more logic into the connection setup. We probably handle the connection types separate and setup the internal connections accordingly.
Draft:
* connectValueChanged Auto -> COP = Auto / SCO = Auto
* connectValueChanged Direct -> COP = Direct / SCO = Direct
* connectValueChanged Queued -> COP = Auto / SCO = Queued
* connectValueChanged BlockingQueued -> Assert(false)

Any thoughts?