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>
This commit is contained in:
Thiago Macieira 2017-09-05 10:25:05 -03:00 committed by J-P Nurmi
parent 0919025ff5
commit 9429226524

View File

@ -277,13 +277,15 @@ void qAddPreRoutine(QtStartUpFunction p)
QStartUpFuncList *list = preRList(); QStartUpFuncList *list = preRList();
if (!list) if (!list)
return; return;
if (QCoreApplication::instance())
p();
// Due to C++11 parallel dynamic initialization, this can be called // Due to C++11 parallel dynamic initialization, this can be called
// from multiple threads. // from multiple threads.
#ifndef QT_NO_THREAD #ifndef QT_NO_THREAD
QMutexLocker locker(&globalRoutinesMutex); QMutexLocker locker(&globalRoutinesMutex);
#endif #endif
if (QCoreApplication::instance())
p();
list->prepend(p); // in case QCoreApplication is re-created, see qt_call_pre_routines 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()) if (!preRList.exists())
return; return;
QVFuncList list;
{
#ifndef QT_NO_THREAD #ifndef QT_NO_THREAD
QMutexLocker locker(&globalRoutinesMutex); QMutexLocker locker(&globalRoutinesMutex);
#endif #endif
QVFuncList *list = &(*preRList); // Unlike qt_call_post_routines, we don't empty the list, because
// Unlike qt_call_post_routines, we don't empty the list, because // Q_COREAPP_STARTUP_FUNCTION is a macro, so the user expects
// Q_COREAPP_STARTUP_FUNCTION is a macro, so the user expects // the function to be executed every time QCoreApplication is created.
// the function to be executed every time QCoreApplication is created. list = *preRList;
for (int i = 0; i < list->count(); ++i) }
list->at(i)(); for (int i = 0; i < list.count(); ++i)
list.at(i)();
} }
void Q_CORE_EXPORT qt_call_post_routines() void Q_CORE_EXPORT qt_call_post_routines()