diff options
Diffstat (limited to 'src/corelib/kernel/qcoreapplication.cpp')
-rw-r--r-- | src/corelib/kernel/qcoreapplication.cpp | 149 |
1 files changed, 76 insertions, 73 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp index 75597f8739..e25049f821 100644 --- a/src/corelib/kernel/qcoreapplication.cpp +++ b/src/corelib/kernel/qcoreapplication.cpp @@ -55,6 +55,7 @@ #include <qfileinfo.h> #include <qmutex.h> #include <private/qloggingregistry_p.h> +#include <qscopeguard.h> #include <qstandardpaths.h> #ifndef QT_NO_QOBJECT #include <qthread.h> @@ -70,6 +71,7 @@ #include <private/qfactoryloader_p.h> #include <private/qfunctions_p.h> #include <private/qlocale_p.h> +#include <private/qlocking_p.h> #include <private/qhooks_p.h> #ifndef QT_NO_QOBJECT @@ -217,16 +219,25 @@ QString QCoreApplicationPrivate::appVersion() const } #endif -QString *QCoreApplicationPrivate::cachedApplicationFilePath = 0; +QString *QCoreApplicationPrivate::cachedApplicationFilePath = nullptr; bool QCoreApplicationPrivate::checkInstance(const char *function) { - bool b = (QCoreApplication::self != 0); + bool b = (QCoreApplication::self != nullptr); if (!b) qWarning("QApplication::%s: Please instantiate the QApplication object first", function); return b; } +#if QT_CONFIG(commandlineparser) +void QCoreApplicationPrivate::addQtOptions(QList<QCommandLineOption> *options) +{ + options->append(QCommandLineOption(QStringLiteral("qmljsdebugger"), + QStringLiteral("Activates the QML/JS debugger with a specified port. The value must be of format port:1234[,block]. \"block\" makes the application wait for a connection."), + QStringLiteral("value"))); +} +#endif + void QCoreApplicationPrivate::processCommandLineArguments() { int j = argc ? 1 : 0; @@ -251,22 +262,13 @@ void QCoreApplicationPrivate::processCommandLineArguments() } if (j < argc) { - argv[j] = 0; + argv[j] = nullptr; argc = j; } } // Support for introspection -#ifndef QT_NO_QOBJECT -QSignalSpyCallbackSet Q_CORE_EXPORT qt_signal_spy_callback_set = { 0, 0, 0, 0 }; - -void qt_register_signal_spy_callbacks(const QSignalSpyCallbackSet &callback_set) -{ - qt_signal_spy_callback_set = callback_set; -} -#endif - extern "C" void Q_CORE_EXPORT qt_startup_hook() { } @@ -294,7 +296,7 @@ void qAddPreRoutine(QtStartUpFunction p) // Due to C++11 parallel dynamic initialization, this can be called // from multiple threads. - QMutexLocker locker(&globalRoutinesMutex); + const auto locker = qt_scoped_lock(globalRoutinesMutex); list->prepend(p); // in case QCoreApplication is re-created, see qt_call_pre_routines } @@ -303,7 +305,7 @@ void qAddPostRoutine(QtCleanUpFunction p) QVFuncList *list = postRList(); if (!list) return; - QMutexLocker locker(&globalRoutinesMutex); + const auto locker = qt_scoped_lock(globalRoutinesMutex); list->prepend(p); } @@ -312,7 +314,7 @@ void qRemovePostRoutine(QtCleanUpFunction p) QVFuncList *list = postRList(); if (!list) return; - QMutexLocker locker(&globalRoutinesMutex); + const auto locker = qt_scoped_lock(globalRoutinesMutex); list->removeAll(p); } @@ -323,7 +325,7 @@ static void qt_call_pre_routines() QVFuncList list; { - QMutexLocker locker(&globalRoutinesMutex); + const auto locker = qt_scoped_lock(globalRoutinesMutex); // 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. @@ -342,7 +344,7 @@ void Q_CORE_EXPORT qt_call_post_routines() QVFuncList list; { // extract the current list and make the stored list empty - QMutexLocker locker(&globalRoutinesMutex); + const auto locker = qt_scoped_lock(globalRoutinesMutex); qSwap(*postRList, list); } @@ -370,25 +372,25 @@ Q_CORE_EXPORT uint qGlobalPostedEventsCount() return currentThreadData->postEventList.size() - currentThreadData->postEventList.startOffset; } -QAbstractEventDispatcher *QCoreApplicationPrivate::eventDispatcher = 0; +QAbstractEventDispatcher *QCoreApplicationPrivate::eventDispatcher = nullptr; #endif // QT_NO_QOBJECT -QCoreApplication *QCoreApplication::self = 0; +QCoreApplication *QCoreApplication::self = nullptr; uint QCoreApplicationPrivate::attribs = (1 << Qt::AA_SynthesizeMouseForUnhandledTouchEvents) | (1 << Qt::AA_SynthesizeMouseForUnhandledTabletEvents); struct QCoreApplicationData { - QCoreApplicationData() Q_DECL_NOTHROW { + QCoreApplicationData() noexcept { applicationNameSet = false; applicationVersionSet = false; } ~QCoreApplicationData() { #ifndef QT_NO_QOBJECT // cleanup the QAdoptedThread created for the main() thread - if (QCoreApplicationPrivate::theMainThread) { - QThreadData *data = QThreadData::get2(QCoreApplicationPrivate::theMainThread); + if (auto *t = QCoreApplicationPrivate::theMainThread.loadAcquire()) { + QThreadData *data = QThreadData::get2(t); data->deref(); // deletes the data and the adopted thread } #endif @@ -458,12 +460,12 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint , aboutToQuitEmitted(false) , threadData_clean(false) #else - , q_ptr(0) + , q_ptr(nullptr) #endif { app_compile_version = flags & 0xffffff; static const char *const empty = ""; - if (argc == 0 || argv == 0) { + if (argc == 0 || argv == nullptr) { argc = 0; argv = const_cast<char **>(&empty); } @@ -488,7 +490,7 @@ QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint #endif QThread *cur = QThread::currentThread(); // note: this may end up setting theMainThread! - if (cur != theMainThread) + if (cur != theMainThread.loadAcquire()) qWarning("WARNING: QApplication was not created in the main() thread."); #endif } @@ -522,7 +524,7 @@ void QCoreApplicationPrivate::cleanupThreadData() #endif // need to clear the state of the mainData, just in case a new QCoreApplication comes along. - QMutexLocker locker(&threadData->postEventList.mutex); + const auto locker = qt_scoped_lock(threadData->postEventList.mutex); for (int i = 0; i < threadData->postEventList.size(); ++i) { const QPostEvent &pe = threadData->postEventList.at(i); if (pe.event) { @@ -554,8 +556,8 @@ void QCoreApplicationPrivate::eventDispatcherReady() QBasicAtomicPointer<QThread> QCoreApplicationPrivate::theMainThread = Q_BASIC_ATOMIC_INITIALIZER(0); QThread *QCoreApplicationPrivate::mainThread() { - Q_ASSERT(theMainThread.load() != 0); - return theMainThread.load(); + Q_ASSERT(theMainThread.loadRelaxed() != 0); + return theMainThread.loadRelaxed(); } bool QCoreApplicationPrivate::threadRequiresCoreApplication() @@ -856,7 +858,7 @@ void QCoreApplicationPrivate::init() #ifndef QT_NO_QOBJECT // use the event dispatcher created by the app programmer (if any) Q_ASSERT(!eventDispatcher); - eventDispatcher = threadData->eventDispatcher.load(); + eventDispatcher = threadData->eventDispatcher.loadRelaxed(); // otherwise we create one if (!eventDispatcher) @@ -864,7 +866,7 @@ void QCoreApplicationPrivate::init() Q_ASSERT(eventDispatcher); if (!eventDispatcher->parent()) { - eventDispatcher->moveToThread(threadData->thread); + eventDispatcher->moveToThread(threadData->thread.loadAcquire()); eventDispatcher->setParent(q); } @@ -872,11 +874,6 @@ void QCoreApplicationPrivate::init() eventDispatcherReady(); #endif -#ifdef QT_EVAL - extern void qt_core_eval_init(QCoreApplicationPrivate::Type); - qt_core_eval_init(application_type); -#endif - processCommandLineArguments(); qt_call_pre_routines(); @@ -898,7 +895,7 @@ QCoreApplication::~QCoreApplication() { qt_call_post_routines(); - self = 0; + self = nullptr; #ifndef QT_NO_QOBJECT QCoreApplicationPrivate::is_app_closing = true; QCoreApplicationPrivate::is_app_running = false; @@ -906,7 +903,7 @@ QCoreApplication::~QCoreApplication() #if QT_CONFIG(thread) // Synchronize and stop the global thread pool threads. - QThreadPool *globalThreadPool = 0; + QThreadPool *globalThreadPool = nullptr; QT_TRY { globalThreadPool = QThreadPool::globalInstance(); } QT_CATCH (...) { @@ -917,10 +914,10 @@ QCoreApplication::~QCoreApplication() #endif #ifndef QT_NO_QOBJECT - d_func()->threadData->eventDispatcher = 0; + d_func()->threadData->eventDispatcher = nullptr; if (QCoreApplicationPrivate::eventDispatcher) QCoreApplicationPrivate::eventDispatcher->closingDown(); - QCoreApplicationPrivate::eventDispatcher = 0; + QCoreApplicationPrivate::eventDispatcher = nullptr; #endif #if QT_CONFIG(library) @@ -1188,7 +1185,7 @@ static bool doNotify(QObject *receiver, QEvent *event) bool QCoreApplicationPrivate::sendThroughApplicationEventFilters(QObject *receiver, QEvent *event) { // We can't access the application event filters outside of the main thread (race conditions) - Q_ASSERT(receiver->d_func()->threadData->thread == mainThread()); + Q_ASSERT(receiver->d_func()->threadData->thread.loadAcquire() == mainThread()); if (extraData) { // application event filters are only called for objects in the GUI thread @@ -1241,7 +1238,7 @@ bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event) // send to all application event filters (only does anything in the main thread) if (QCoreApplication::self - && receiver->d_func()->threadData->thread == mainThread() + && receiver->d_func()->threadData->thread.loadAcquire() == mainThread() && QCoreApplication::self->d_func()->sendThroughApplicationEventFilters(receiver, event)) { filtered = true; return filtered; @@ -1313,7 +1310,7 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags) QThreadData *data = QThreadData::current(); if (!data->hasEventDispatcher()) return; - data->eventDispatcher.load()->processEvents(flags); + data->eventDispatcher.loadRelaxed()->processEvents(flags); } /*! @@ -1345,7 +1342,7 @@ void QCoreApplication::processEvents(QEventLoop::ProcessEventsFlags flags, int m return; QElapsedTimer start; start.start(); - while (data->eventDispatcher.load()->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) { + while (data->eventDispatcher.loadRelaxed()->processEvents(flags & ~QEventLoop::WaitForMoreEvents)) { if (start.elapsed() > ms) break; } @@ -1710,7 +1707,7 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type ++data->postEventList.recursion; - QMutexLocker locker(&data->postEventList.mutex); + auto locker = qt_unique_lock(data->postEventList.mutex); // by default, we assume that the event dispatcher can go to sleep after // processing all events. if any new events are posted while we send @@ -1749,7 +1746,7 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type --data->postEventList.recursion; if (!data->postEventList.recursion && !data->canWait && data->hasEventDispatcher()) - data->eventDispatcher.load()->wakeUp(); + data->eventDispatcher.loadRelaxed()->wakeUp(); // clear the global list, i.e. remove everything that was // delivered. @@ -1826,13 +1823,8 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type // for the next event. const_cast<QPostEvent &>(pe).event = 0; - struct MutexUnlocker - { - QMutexLocker &m; - MutexUnlocker(QMutexLocker &m) : m(m) { m.unlock(); } - ~MutexUnlocker() { m.relock(); } - }; - MutexUnlocker unlocker(locker); + locker.unlock(); + const auto relocker = qScopeGuard([&locker] { locker.lock(); }); QScopedPointer<QEvent> event_deleter(e); // will delete the event (with the mutex unlocked) @@ -1869,7 +1861,7 @@ void QCoreApplicationPrivate::sendPostedEvents(QObject *receiver, int event_type void QCoreApplication::removePostedEvents(QObject *receiver, int eventType) { QThreadData *data = receiver ? receiver->d_func()->threadData : QThreadData::current(); - QMutexLocker locker(&data->postEventList.mutex); + auto locker = qt_unique_lock(data->postEventList.mutex); // the QObject destructor calls this function directly. this can // happen while the event loop is in the middle of posting events, @@ -1932,7 +1924,7 @@ void QCoreApplicationPrivate::removePostedEvent(QEvent * event) QThreadData *data = QThreadData::current(); - QMutexLocker locker(&data->postEventList.mutex); + const auto locker = qt_scoped_lock(data->postEventList.mutex); if (data->postEventList.size() == 0) { #if defined(QT_DEBUG) @@ -2000,7 +1992,7 @@ void QCoreApplicationPrivate::deref() void QCoreApplicationPrivate::maybeQuit() { - if (quitLockRef.load() == 0 && in_exec && quitLockRefEnabled && shouldQuit()) + if (quitLockRef.loadRelaxed() == 0 && in_exec && quitLockRefEnabled && shouldQuit()) QCoreApplication::postEvent(QCoreApplication::instance(), new QEvent(QEvent::Quit)); } @@ -2662,7 +2654,7 @@ QString QCoreApplication::applicationVersion() #if QT_CONFIG(library) -Q_GLOBAL_STATIC_WITH_ARGS(QMutex, libraryPathMutex, (QMutex::Recursive)) +Q_GLOBAL_STATIC(QRecursiveMutex, libraryPathMutex) /*! Returns a list of paths that the application will search when @@ -2701,7 +2693,14 @@ Q_GLOBAL_STATIC_WITH_ARGS(QMutex, libraryPathMutex, (QMutex::Recursive)) QStringList QCoreApplication::libraryPaths() { QMutexLocker locker(libraryPathMutex()); + return libraryPathsLocked(); +} +/*! + \internal +*/ +QStringList QCoreApplication::libraryPathsLocked() +{ if (coreappdata()->manual_libpaths) return *(coreappdata()->manual_libpaths); @@ -2709,18 +2708,22 @@ QStringList QCoreApplication::libraryPaths() QStringList *app_libpaths = new QStringList; coreappdata()->app_libpaths.reset(app_libpaths); - QString libPathEnv = qEnvironmentVariable("QT_PLUGIN_PATH"); - if (!libPathEnv.isEmpty()) { - QStringList paths = libPathEnv.split(QDir::listSeparator(), QString::SkipEmptyParts); - for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) { - QString canonicalPath = QDir(*it).canonicalPath(); - if (!canonicalPath.isEmpty() - && !app_libpaths->contains(canonicalPath)) { - app_libpaths->append(canonicalPath); + auto setPathsFromEnv = [&](QString libPathEnv) { + if (!libPathEnv.isEmpty()) { + QStringList paths = libPathEnv.split(QDir::listSeparator(), QString::SkipEmptyParts); + for (QStringList::const_iterator it = paths.constBegin(); it != paths.constEnd(); ++it) { + QString canonicalPath = QDir(*it).canonicalPath(); + if (!canonicalPath.isEmpty() + && !app_libpaths->contains(canonicalPath)) { + app_libpaths->append(canonicalPath); + } } } - } - + }; + setPathsFromEnv(qEnvironmentVariable("QT_PLUGIN_PATH")); +#ifdef Q_OS_ANDROID + setPathsFromEnv(qEnvironmentVariable("QT_BUNDLED_LIBS_PATH")); +#endif #ifdef Q_OS_DARWIN // Check the main bundle's PlugIns directory as this is a standard location for Apple OSes. // Note that the QLibraryInfo::PluginsPath below will coincidentally be the same as this value @@ -2777,7 +2780,7 @@ void QCoreApplication::setLibraryPaths(const QStringList &paths) // When the application is constructed it should still amend the paths. So we keep the originals // around, and even create them if they don't exist, yet. if (!coreappdata()->app_libpaths) - libraryPaths(); + libraryPathsLocked(); if (coreappdata()->manual_libpaths) *(coreappdata()->manual_libpaths) = paths; @@ -2820,7 +2823,7 @@ void QCoreApplication::addLibraryPath(const QString &path) return; } else { // make sure that library paths are initialized - libraryPaths(); + libraryPathsLocked(); QStringList *app_libpaths = coreappdata()->app_libpaths.data(); if (app_libpaths->contains(canonicalPath)) return; @@ -2859,7 +2862,7 @@ void QCoreApplication::removeLibraryPath(const QString &path) return; } else { // make sure that library paths is initialized - libraryPaths(); + libraryPathsLocked(); QStringList *app_libpaths = coreappdata()->app_libpaths.data(); if (!app_libpaths->contains(canonicalPath)) return; @@ -2912,7 +2915,7 @@ void QCoreApplication::installNativeEventFilter(QAbstractNativeEventFilter *filt return; } - QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(QCoreApplicationPrivate::theMainThread); + QAbstractEventDispatcher *eventDispatcher = QAbstractEventDispatcher::instance(QCoreApplicationPrivate::theMainThread.loadAcquire()); if (!filterObj || !eventDispatcher) return; eventDispatcher->installNativeEventFilter(filterObj); @@ -2968,8 +2971,8 @@ bool QCoreApplication::hasPendingEvents() */ QAbstractEventDispatcher *QCoreApplication::eventDispatcher() { - if (QCoreApplicationPrivate::theMainThread) - return QCoreApplicationPrivate::theMainThread.load()->eventDispatcher(); + if (QCoreApplicationPrivate::theMainThread.loadAcquire()) + return QCoreApplicationPrivate::theMainThread.loadRelaxed()->eventDispatcher(); return 0; } @@ -2981,7 +2984,7 @@ QAbstractEventDispatcher *QCoreApplication::eventDispatcher() */ void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher) { - QThread *mainThread = QCoreApplicationPrivate::theMainThread; + QThread *mainThread = QCoreApplicationPrivate::theMainThread.loadAcquire(); if (!mainThread) mainThread = QThread::currentThread(); // will also setup theMainThread mainThread->setEventDispatcher(eventDispatcher); |