diff options
author | Liang Qi <liang.qi@qt.io> | 2017-09-26 16:08:55 +0200 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2017-09-26 16:14:54 +0200 |
commit | aadfe7d634de04519102c5827ca885dc2e2199c9 (patch) | |
tree | d92db346ca95332b177036a53f1f6beb2e24fb74 /src/corelib/kernel/qcoreapplication.cpp | |
parent | 4b6c1448047362b8c38d265e6414f0e3e59b8d37 (diff) | |
parent | a732e16d5fd9dbf8a0289fec9f948b12e9ba2c19 (diff) |
Merge remote-tracking branch 'origin/5.10' into dev
Conflicts:
src/gui/kernel/qguiapplication.cpp
src/platformsupport/input/libinput/qlibinputpointer.cpp
src/plugins/platforminputcontexts/ibus/qibusplatforminputcontext.h
src/plugins/platforms/cocoa/qcocoawindow.h
src/testlib/qtestsystem.h
Change-Id: I5975ffb3261c2dd82fe02ec4e57df7c0950226c5
Diffstat (limited to 'src/corelib/kernel/qcoreapplication.cpp')
-rw-r--r-- | src/corelib/kernel/qcoreapplication.cpp | 61 |
1 files changed, 45 insertions, 16 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 19db06b015..d1640bdc49 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -263,7 +263,7 @@ Q_GLOBAL_STATIC(QStartUpFuncList, preRList) typedef QList<QtCleanUpFunction> QVFuncList; Q_GLOBAL_STATIC(QVFuncList, postRList) #ifndef QT_NO_QOBJECT -static QBasicMutex globalPreRoutinesMutex; +static QBasicMutex globalRoutinesMutex; #endif /*! @@ -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(&globalPreRoutinesMutex); + QMutexLocker locker(&globalRoutinesMutex); #endif - if (QCoreApplication::instance()) - p(); list->prepend(p); // in case QCoreApplication is re-created, see qt_call_pre_routines } @@ -292,6 +294,9 @@ void qAddPostRoutine(QtCleanUpFunction p) QVFuncList *list = postRList(); if (!list) return; +#ifndef QT_NO_THREAD + QMutexLocker locker(&globalRoutinesMutex); +#endif list->prepend(p); } @@ -300,6 +305,9 @@ void qRemovePostRoutine(QtCleanUpFunction p) QVFuncList *list = postRList(); if (!list) return; +#ifndef QT_NO_THREAD + QMutexLocker locker(&globalRoutinesMutex); +#endif list->removeAll(p); } @@ -308,15 +316,18 @@ static void qt_call_pre_routines() if (!preRList.exists()) return; + QVFuncList list; + { #ifndef QT_NO_THREAD - QMutexLocker locker(&globalPreRoutinesMutex); + 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() @@ -324,9 +335,21 @@ void Q_CORE_EXPORT qt_call_post_routines() if (!postRList.exists()) return; - QVFuncList *list = &(*postRList); - while (!list->isEmpty()) - (list->takeFirst())(); + forever { + QVFuncList list; + { + // extract the current list and make the stored list empty +#ifndef QT_NO_THREAD + QMutexLocker locker(&globalRoutinesMutex); +#endif + qSwap(*postRList, list); + } + + if (list.isEmpty()) + break; + for (QtCleanUpFunction f : qAsConst(list)) + f(); + } } @@ -2864,6 +2887,7 @@ void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatc /*! \fn void qAddPostRoutine(QtCleanUpFunction ptr) + \threadsafe \relates QCoreApplication Adds a global routine that will be called from the QCoreApplication @@ -2877,10 +2901,10 @@ void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatc \snippet code/src_corelib_kernel_qcoreapplication.cpp 4 - Note that for an application- or module-wide cleanup, qaddPostRoutine() + Note that for an application- or module-wide cleanup, qAddPostRoutine() is often not suitable. For example, if the program is split into dynamically loaded modules, the relevant module may be unloaded long before the - QCoreApplication destructor is called. In such cases, if using qaddPostRoutine() + QCoreApplication destructor is called. In such cases, if using qAddPostRoutine() is still desirable, qRemovePostRoutine() can be used to prevent a routine from being called by the QCoreApplication destructor. For example, if that routine was called before the module was unloaded. @@ -2896,11 +2920,14 @@ void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatc By selecting the right parent object, this can often be made to clean up the module's data at the right moment. + \note This function has been thread-safe since Qt 5.10. + \sa qRemovePostRoutine() */ /*! \fn void qRemovePostRoutine(QtCleanUpFunction ptr) + \threadsafe \relates QCoreApplication \since 5.3 @@ -2909,6 +2936,8 @@ void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatc must have been previously added to the list by a call to qAddPostRoutine(), otherwise this function has no effect. + \note This function has been thread-safe since Qt 5.10. + \sa qAddPostRoutine() */ |