summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qcoreapplication.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qcoreapplication.cpp')
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp149
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);