summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/io/qprocess_unix.cpp15
-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
-rw-r--r--tests/auto/corelib/io/io.pro1
-rw-r--r--tests/auto/corelib/io/qprocess-noapplication/qprocess-noapplication.pro5
-rw-r--r--tests/auto/corelib/io/qprocess-noapplication/tst_qprocessnoapplication.cpp84
7 files changed, 98 insertions, 28 deletions
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 1ef7af586f..0a928e4603 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -177,7 +177,7 @@ static QProcessManager *processManager()
QMutexLocker locker(&processManagerGlobalMutex);
if (!processManagerInstance)
- QProcessPrivate::initializeProcessManager();
+ new QProcessManager;
Q_ASSERT(processManagerInstance);
return processManagerInstance;
@@ -185,9 +185,6 @@ static QProcessManager *processManager()
QProcessManager::QProcessManager()
{
- // can only be called from main thread
- Q_ASSERT(!qApp || qApp->thread() == QThread::currentThread());
-
#if defined (QPROCESS_DEBUG)
qDebug() << "QProcessManager::QProcessManager()";
#endif
@@ -1434,15 +1431,7 @@ bool QProcessPrivate::startDetached(const QString &program, const QStringList &a
void QProcessPrivate::initializeProcessManager()
{
- 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);
- }
+ (void) processManager();
}
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 1e4a6f4c8c..df0ffce12d 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -392,16 +392,6 @@ 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()
{
@@ -625,6 +615,12 @@ void QCoreApplication::init()
d->appendApplicationPathToLibraryPaths();
#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);
@@ -2364,5 +2360,3 @@ void QCoreApplication::setEventDispatcher(QAbstractEventDispatcher *eventDispatc
*/
QT_END_NAMESPACE
-
-#include "moc_qcoreapplication.cpp"
diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h
index 388877cbec..622139e6f8 100644
--- a/src/corelib/kernel/qcoreapplication.h
+++ b/src/corelib/kernel/qcoreapplication.h
@@ -178,7 +178,6 @@ 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 393ae1c55a..321f6905a4 100644
--- a/src/corelib/kernel/qcoreapplication_p.h
+++ b/src/corelib/kernel/qcoreapplication_p.h
@@ -76,8 +76,6 @@ public:
bool sendThroughObjectEventFilters(QObject *, QEvent *);
bool notify_helper(QObject *, QEvent *);
- void _q_initializeProcessManager();
-
QString appName() const;
virtual void createEventDispatcher();
static void removePostedEvent(QEvent *);
diff --git a/tests/auto/corelib/io/io.pro b/tests/auto/corelib/io/io.pro
index f6542d9fd3..03b42a2cbb 100644
--- a/tests/auto/corelib/io/io.pro
+++ b/tests/auto/corelib/io/io.pro
@@ -16,6 +16,7 @@ SUBDIRS=\
qipaddress \
qnodebug \
qprocess \
+ qprocess-noapplication \
qprocessenvironment \
qresourceengine \
qsettings \
diff --git a/tests/auto/corelib/io/qprocess-noapplication/qprocess-noapplication.pro b/tests/auto/corelib/io/qprocess-noapplication/qprocess-noapplication.pro
new file mode 100644
index 0000000000..2f409ebdbc
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess-noapplication/qprocess-noapplication.pro
@@ -0,0 +1,5 @@
+CONFIG += testcase
+CONFIG += parallel_test
+CONFIG -= app_bundle debug_and_release_target
+QT = core testlib
+SOURCES = tst_qprocessnoapplication.cpp
diff --git a/tests/auto/corelib/io/qprocess-noapplication/tst_qprocessnoapplication.cpp b/tests/auto/corelib/io/qprocess-noapplication/tst_qprocessnoapplication.cpp
new file mode 100644
index 0000000000..33146cafd1
--- /dev/null
+++ b/tests/auto/corelib/io/qprocess-noapplication/tst_qprocessnoapplication.cpp
@@ -0,0 +1,84 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Intel Corporation.
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtCore/QCoreApplication>
+#include <QtCore/QProcess>
+#include <QtCore/QThread>
+#include <QtTest>
+
+class tst_QProcessNoApplication : public QObject
+{
+ Q_OBJECT
+
+private Q_SLOTS:
+ void initializationDeadlock();
+};
+
+void tst_QProcessNoApplication::initializationDeadlock()
+{
+ // see QTBUG-27260
+ // QProcess on Unix uses (or used to, at the time of the writing of this test)
+ // a global class called QProcessManager.
+ // This class is instantiated (or was) only in the main thread, which meant that
+ // blocking the main thread while waiting for QProcess could mean a deadlock.
+
+ struct MyThread : public QThread
+ {
+ void run()
+ {
+ // what we execute does not matter, as long as we try to
+ // and that the process exits
+ QProcess::execute("true");
+ }
+ };
+
+ static char argv0[] = "tst_QProcessNoApplication";
+ char *argv[] = { argv0, 0 };
+ int argc = 1;
+ QCoreApplication app(argc, argv);
+ MyThread thread;
+ thread.start();
+ QVERIFY(thread.wait(10000));
+}
+
+QTEST_APPLESS_MAIN(tst_QProcessNoApplication)
+
+#include "tst_qprocessnoapplication.moc"