summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
authorHarald Fernengel <harald.fernengel@nokia.com>2010-12-20 13:26:39 (GMT)
committerHarald Fernengel <harald.fernengel@nokia.com>2010-12-20 13:26:39 (GMT)
commitdaba2c507ad42c66dafa6a29cffa94e9641e0c58 (patch)
tree3e94b28fa63f5d8120a38f74d829f78f40d59b5c /src/corelib
parent48e7c71d1165f0c60f56e0b769b35df2658e8e96 (diff)
downloadQt-daba2c507ad42c66dafa6a29cffa94e9641e0c58.zip
Qt-daba2c507ad42c66dafa6a29cffa94e9641e0c58.tar.gz
Qt-daba2c507ad42c66dafa6a29cffa94e9641e0c58.tar.bz2
Delay creation of the process manager
The *nix process manager would create a pipe on every startup. In order to improve startup speed, the QProcessManager is now created when first needed. Reviewed-by: Robert Griebl
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/io/qprocess_unix.cpp30
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp18
-rw-r--r--src/corelib/kernel/qcoreapplication.h1
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h2
4 files changed, 41 insertions, 10 deletions
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 216c382..e52d132 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -169,17 +169,27 @@ private:
Q_GLOBAL_STATIC(QMutex, processManagerGlobalMutex)
-static QProcessManager *processManager() {
+static QProcessManager *processManagerInstance = 0;
+
+static QProcessManager *processManager()
+{
// The constructor of QProcessManager should be called only once
// so we cannot use Q_GLOBAL_STATIC directly for QProcessManager
QMutex *mutex = processManagerGlobalMutex();
QMutexLocker locker(mutex);
- static QProcessManager processManager;
- return &processManager;
+
+ if (!processManagerInstance)
+ QProcessPrivate::initializeProcessManager();
+
+ Q_ASSERT(processManagerInstance);
+ return processManagerInstance;
}
QProcessManager::QProcessManager()
{
+ // can only be called from main thread
+ Q_ASSERT(!qApp || qApp->thread() == QThread::currentThread());
+
#if defined (QPROCESS_DEBUG)
qDebug() << "QProcessManager::QProcessManager()";
#endif
@@ -198,6 +208,8 @@ QProcessManager::QProcessManager()
::sigaction(SIGCHLD, &action, &oldAction);
if (oldAction.sa_handler != qt_sa_sigchld_handler)
qt_sa_old_sigchld_handler = oldAction.sa_handler;
+
+ processManagerInstance = this;
}
QProcessManager::~QProcessManager()
@@ -226,6 +238,8 @@ QProcessManager::~QProcessManager()
if (oldAction.sa_handler != qt_sa_sigchld_handler) {
::sigaction(SIGCHLD, &oldAction, 0);
}
+
+ processManagerInstance = 0;
}
void QProcessManager::run()
@@ -1289,7 +1303,15 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a
void QProcessPrivate::initializeProcessManager()
{
- (void) processManager();
+ if (qApp && qApp->thread() != QThread::currentThread()) {
+ // The process manager must be initialized in the main thread
+ // Note: The call below will re-enter this function, but in the right thread,
+ // so the else statement below will be executed.
+ QMetaObject::invokeMethod(qApp, "_q_initializeProcessManager", Qt::BlockingQueuedConnection);
+ } else {
+ static QProcessManager processManager;
+ Q_UNUSED(processManager);
+ }
}
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 0f95ee0..799433b 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -336,6 +336,16 @@ void QCoreApplicationPrivate::createEventDispatcher()
#endif
}
+void QCoreApplicationPrivate::_q_initializeProcessManager()
+{
+#ifndef QT_NO_PROCESS
+# ifdef Q_OS_UNIX
+ QProcessPrivate::initializeProcessManager();
+# endif
+#endif
+}
+
+
QThread *QCoreApplicationPrivate::theMainThread = 0;
QThread *QCoreApplicationPrivate::mainThread()
{
@@ -600,12 +610,6 @@ void QCoreApplication::init()
}
#endif
-#if defined(Q_OS_UNIX) && !(defined(QT_NO_PROCESS))
- // Make sure the process manager thread object is created in the main
- // thread.
- QProcessPrivate::initializeProcessManager();
-#endif
-
#ifdef QT_EVAL
extern void qt_core_eval_init(uint);
qt_core_eval_init(d->application_type);
@@ -2666,3 +2670,5 @@ int QCoreApplication::loopLevel()
*/
QT_END_NAMESPACE
+
+#include "moc_qcoreapplication.cpp"
diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h
index f1c7c26..17e784e 100644
--- a/src/corelib/kernel/qcoreapplication.h
+++ b/src/corelib/kernel/qcoreapplication.h
@@ -205,6 +205,7 @@ protected:
QCoreApplication(QCoreApplicationPrivate &p);
private:
+ Q_PRIVATE_SLOT(d_func(), void _q_initializeProcessManager())
static bool sendSpontaneousEvent(QObject *receiver, QEvent *event);
bool notifyInternal(QObject *receiver, QEvent *event);
diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h
index 2355c37..aafa821 100644
--- a/src/corelib/kernel/qcoreapplication_p.h
+++ b/src/corelib/kernel/qcoreapplication_p.h
@@ -82,6 +82,8 @@ public:
bool sendThroughObjectEventFilters(QObject *, QEvent *);
bool notify_helper(QObject *, QEvent *);
+ void _q_initializeProcessManager();
+
virtual QString appName() const;
virtual void createEventDispatcher();
static void removePostedEvent(QEvent *);