Skip to content

Fix a curious race condition when initializing AkThread-derived classes

Daniel Vrátil requested to merge work/dvratil/fix-akthread-race into master

When a class derived from AkThread is constructed, the AkThread constructor is called first. In this constructor AkThread starts a new thread and moves the object into that thread. Then it uses QMetaObject::invokeMethod to schedule invoking the virtual this->init() method on the new thread. If the new thread is very fast to start, there's a chance that it will run the init() method before the main thread manages to reach the derived class constructor and update the vtable. In such situation, the runtime will invoke AkThread::init() instead of Derived::init(), and it may also race with the code in Derived constructor being executed on the main thread.

The only reliable solution for this is to request invoking the init() method only after the entire Derived object has been constructed, that is outside of the constructor call chain. As such, this change introduces AkThread::create() static template method which constructs AkThread-derived object and then invokes the init() method.

Merge request reports