Details
-
Bug
-
Resolution: Unresolved
-
P2: Important
-
None
-
5.12.2, 5.15.0 RC2
-
None
Description
The Q_PLUGIN_INSTANCE is not thread safe - while the static block ensures that instance_ is set to null once, it is possible that multiple threads could perform the check that if (!_instance) and then create more than one actual object. (While this is unlikely in practice, our thread sanitizer picked this up)
By throwing the whole initialization check into a lambda and calling it we don't have this problem
--- a/src/corelib/plugin/qplugin.h +++ b/src/corelib/plugin/qplugin.h @@ -129,11 +129,10 @@ #define Q_PLUGIN_INSTANCE(IMPLEMENTATION) \ { \ - static QT_PREPEND_NAMESPACE(QPointer)<QT_PREPEND_NAMESPACE(QObject)> _instance; \ - if (!_instance) { \ + static QT_PREPEND_NAMESPACE(QPointer)<QT_PREPEND_NAMESPACE(QObject)> _instance = [] { \ QT_PLUGIN_RESOURCE_INIT \ - _instance = new IMPLEMENTATION; \ - } \ + return new IMPLEMENTATION; \ + }(); \ return _instance; \ }