This is great, but it creates some additional complexities for those of us writing libraries to be used by such applications. Since I've run into problems in a couple of places now in Frameworks code, I thought I'd share ...
One of the main sources of problems is classes which create private data members (which is nearly all of them) which require an event loop for signals and slots, network, dbus, etc. If these objects have a QObject parent and that parent is moved to another thread with QObject::moveToThread, then all stays happy and fine: the private object is moved to the new thread automatically and continues event processing there.
However, if that object does not have a parent the this does not happen. Should the object the application instantiated be moved to another thread, then the private object gets left behind in the original thread. This becomes a problem if that original thread is then stopped. Or, worse, doesn't have an event loop to begin with.
(In Sprinter, some objects are created in QRunnables which are run in a QThreadPool without an event loop; these objects are then moved to a thread with an event loop .. you can see the problem.)
Even worse are singletons in libraries. These don't have a parent that they can follow between threads and they often exist for the lifespan of the library's usage. Which means that if a class from the library which uses such an internal singleton is instantiated in thread A and, when the work is complete, thread A is stopped; when another class that uses that internal singleton is instantiated, the singleton will be stuck in a thread that has no event loop.
This is usually entirely transparent to the application developer using the library, so the application writer is unlikely to be aware of these objects floating around which makes it look like things just magically break. If these private objects were public, then at least the application developer could work around these limitations in the context of the threading model they are implementing.
If you are writing a Qt library with private objects that require event loops and which do not have QObject parents, there are a few things that you can do:
- Warn application developers in the apidox; this doesn't fix anything directly, but at least the application developer can inform themselves and either not use the library with threads or work around it (e.g. by instantiating affected classes in the main app thread only)
- Ensure these private objects are in a thread with an event loop; that might mean instantiating them in the application thread or, in the case of computationally intensive objects, giving them their very own thread to wallow in.
- Do nothing and enjoy watching developers using your library in threads stare at their screen wondering why the object they just new'd is apparently alive and kicking, but not doing what it should. ;)