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();
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()