diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2017-09-05 10:25:05 -0300 |
---|---|---|
committer | J-P Nurmi <jpnurmi@qt.io> | 2017-09-06 06:48:39 +0000 |
commit | 942922652481347659a0dae78758c334778a58d2 (patch) | |
tree | 0cef2eade6c6c3fb99a937546a780ce224cbc00a /src | |
parent | 0919025ff53c36f9f883ad5a32414231d81ae38a (diff) |
Don't call the qAddPreRoutine routines with the mutex lock held
One of those routines could recurse back. This was a pre-existing
problem for Pre-Pre routines, but commit a92ee2518fdbd77fcbe3f8ef4f412aa
made qAddPostRoutine also use the same mutex.
Task-number: QTBUG-63008
Change-Id: I38341f8155354cc4a776fffd14e17a037d25475f
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Reviewed-by: J-P Nurmi <jpnurmi@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/corelib/kernel/qcoreapplication.cpp | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index a1f9d494d5..609e52d9d2 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -277,13 +277,15 @@ void qAddPreRoutine(QtStartUpFunction p) QStartUpFuncList *list = preRList(); if (!list) return; + + if (QCoreApplication::instance()) + p(); + // Due to C++11 parallel dynamic initialization, this can be called // from multiple threads. #ifndef QT_NO_THREAD QMutexLocker locker(&globalRoutinesMutex); #endif - if (QCoreApplication::instance()) - p(); list->prepend(p); // in case QCoreApplication is re-created, see qt_call_pre_routines } @@ -314,15 +316,18 @@ static void qt_call_pre_routines() if (!preRList.exists()) return; + QVFuncList list; + { #ifndef QT_NO_THREAD - QMutexLocker locker(&globalRoutinesMutex); + QMutexLocker locker(&globalRoutinesMutex); #endif - QVFuncList *list = &(*preRList); - // Unlike qt_call_post_routines, we don't empty the list, because - // Q_COREAPP_STARTUP_FUNCTION is a macro, so the user expects - // the function to be executed every time QCoreApplication is created. - for (int i = 0; i < list->count(); ++i) - list->at(i)(); + // Unlike qt_call_post_routines, we don't empty the list, because + // Q_COREAPP_STARTUP_FUNCTION is a macro, so the user expects + // the function to be executed every time QCoreApplication is created. + list = *preRList; + } + for (int i = 0; i < list.count(); ++i) + list.at(i)(); } void Q_CORE_EXPORT qt_call_post_routines() |