summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp36
-rw-r--r--src/corelib/kernel/qcoreapplication.h6
-rw-r--r--src/corelib/kernel/qcoreapplication_p.h4
-rw-r--r--src/corelib/kernel/qeventloop.cpp105
-rw-r--r--src/corelib/kernel/qeventloop.h17
-rw-r--r--src/corelib/kernel/qeventloop_p.h83
6 files changed, 239 insertions, 12 deletions
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index ae30167a42..a248e18a6a 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -271,6 +271,8 @@ struct QCoreApplicationData {
Q_GLOBAL_STATIC(QCoreApplicationData, coreappdata)
+static bool quitLockRefEnabled = true;
+
QCoreApplicationPrivate::QCoreApplicationPrivate(int &aargc, char **aargv, uint flags)
: QObjectPrivate(), argc(aargc), argv(aargv), application_type(0), eventFilter(0),
in_exec(false), aboutToQuitEmitted(false), threadData_clean(false)
@@ -649,6 +651,29 @@ bool QCoreApplication::testAttribute(Qt::ApplicationAttribute attribute)
return QCoreApplicationPrivate::testAttribute(attribute);
}
+/*!/
+ Returns true if the use of the QEventLoopLocker feature can cause the
+ application to quit, otherwise returns false.
+
+ \sa QEventLoopLocker
+ */
+bool QCoreApplication::isQuitLockEnabled()
+{
+ return quitLockRefEnabled;
+}
+
+/*!
+ Enables the ability of the QEventLoopLocker feature to quit
+ the application.
+
+ If disabled, the use of QEventLoopLocker will not quit the application.
+
+ \sa QEventLoopLocker
+ */
+void QCoreApplication::setQuitLockEnabled(bool enabled)
+{
+ quitLockRefEnabled = enabled;
+}
/*!
\internal
@@ -1476,6 +1501,17 @@ bool QCoreApplication::event(QEvent *e)
\sa QObject::tr(), QObject::trUtf8(), QString::fromUtf8()
*/
+void QCoreApplicationPrivate::ref()
+{
+ quitLockRef.ref();
+}
+
+void QCoreApplicationPrivate::deref()
+{
+ if (!quitLockRef.deref() && in_exec && quitLockRefEnabled)
+ QCoreApplication::postEvent(qApp, new QEvent(QEvent::Quit));
+}
+
/*!
Tells the application to exit with return code 0 (success).
Equivalent to calling QCoreApplication::exit(0).
diff --git a/src/corelib/kernel/qcoreapplication.h b/src/corelib/kernel/qcoreapplication.h
index 45583a67fa..d1fba3b63c 100644
--- a/src/corelib/kernel/qcoreapplication.h
+++ b/src/corelib/kernel/qcoreapplication.h
@@ -71,6 +71,7 @@ class Q_CORE_EXPORT QCoreApplication : public QObject
Q_PROPERTY(QString applicationVersion READ applicationVersion WRITE setApplicationVersion)
Q_PROPERTY(QString organizationName READ organizationName WRITE setOrganizationName)
Q_PROPERTY(QString organizationDomain READ organizationDomain WRITE setOrganizationDomain)
+ Q_PROPERTY(bool quitLockEnabled READ isQuitLockEnabled WRITE setQuitLockEnabled)
Q_DECLARE_PRIVATE(QCoreApplication)
public:
@@ -160,6 +161,9 @@ public:
EventFilter setEventFilter(EventFilter filter);
bool filterEvent(void *message, long *result);
+ static bool isQuitLockEnabled();
+ static void setQuitLockEnabled(bool enabled);
+
public Q_SLOTS:
static void quit();
@@ -183,7 +187,7 @@ private:
void init();
static QCoreApplication *self;
-
+
Q_DISABLE_COPY(QCoreApplication)
friend class QEventDispatcherUNIXPrivate;
diff --git a/src/corelib/kernel/qcoreapplication_p.h b/src/corelib/kernel/qcoreapplication_p.h
index b5b6c0d5f2..861a046f16 100644
--- a/src/corelib/kernel/qcoreapplication_p.h
+++ b/src/corelib/kernel/qcoreapplication_p.h
@@ -89,6 +89,10 @@ public:
static QString macMenuBarName();
#endif
+ QAtomicInt quitLockRef;
+ void ref();
+ void deref();
+
static QThread *theMainThread;
static QThread *mainThread();
static bool checkInstance(const char *method);
diff --git a/src/corelib/kernel/qeventloop.cpp b/src/corelib/kernel/qeventloop.cpp
index 0c1b8c77ff..8b0ec85679 100644
--- a/src/corelib/kernel/qeventloop.cpp
+++ b/src/corelib/kernel/qeventloop.cpp
@@ -43,24 +43,15 @@
#include "qabstracteventdispatcher.h"
#include "qcoreapplication.h"
+#include "qcoreapplication_p.h"
#include "qelapsedtimer.h"
#include "qobject_p.h"
+#include "qeventloop_p.h"
#include <private/qthread_p.h>
QT_BEGIN_NAMESPACE
-class QEventLoopPrivate : public QObjectPrivate
-{
- Q_DECLARE_PUBLIC(QEventLoop)
-public:
- inline QEventLoopPrivate()
- : exit(true), inExec(false), returnCode(-1)
- { }
- bool exit, inExec;
- int returnCode;
-};
-
/*!
\class QEventLoop
\brief The QEventLoop class provides a means of entering and leaving an event loop.
@@ -305,6 +296,17 @@ void QEventLoop::wakeUp()
d->threadData->eventDispatcher->wakeUp();
}
+
+bool QEventLoop::event(QEvent *event)
+{
+ if (event->type() == QEvent::Quit) {
+ quit();
+ return true;
+ } else {
+ return QObject::event(event);
+ }
+}
+
/*!
Tells the event loop to exit normally.
@@ -315,4 +317,85 @@ void QEventLoop::wakeUp()
void QEventLoop::quit()
{ exit(0); }
+
+class QEventLoopLockerPrivate
+{
+public:
+ explicit QEventLoopLockerPrivate(QEventLoopPrivate *loop)
+ : loop(loop), app(0)
+ {
+ loop->ref();
+ }
+
+ explicit QEventLoopLockerPrivate(QCoreApplicationPrivate *app)
+ : loop(0), app(app)
+ {
+ app->ref();
+ }
+
+ ~QEventLoopLockerPrivate()
+ {
+ if (loop)
+ loop->deref();
+ else
+ app->deref();
+ }
+
+private:
+ QEventLoopPrivate *loop;
+ QCoreApplicationPrivate *app;
+};
+
+/*!
+ \class QEventLoopLocker
+ \brief The QEventLoopLocker class provides a means to quit an event loop when it is no longer needed.
+
+ The QEventLoopLocker operates on particular objects - either a QCoreApplication
+ instance or a QEventLoop instance.
+
+ This makes it possible to, for example, run a batch of jobs with an event loop
+ and exit that event loop after the last job is finished. That is accomplished
+ by keeping a QEventLoopLocker with each job instance.
+
+ The variant which operates on QCoreApplication makes it possible to finish
+ asynchronously running jobs after the last gui window has been closed. This
+ can be useful for example for running a job which uploads data to a network.
+
+ \sa QEventLoop, QCoreApplication
+*/
+
+/*!
+ Creates an event locker operating on the \p app.
+
+ The application will quit when there are no more QEventLoopLockers operating on it.
+
+ \sa QCoreApplication::quit(), QCoreApplication::isQuitLockEnabled()
+ */
+QEventLoopLocker::QEventLoopLocker()
+ : d_ptr(new QEventLoopLockerPrivate(static_cast<QCoreApplicationPrivate*>(QObjectPrivate::get(QCoreApplication::instance()))))
+{
+
+}
+
+/*!
+ Creates an event locker operating on the \p app.
+
+ This particular QEventLoop will quit when there are no more QEventLoopLockers operating on it.
+
+ \sa QEventLoop::quit()
+ */
+QEventLoopLocker::QEventLoopLocker(QEventLoop *loop)
+ : d_ptr(new QEventLoopLockerPrivate(static_cast<QEventLoopPrivate*>(QObjectPrivate::get(loop))))
+{
+
+}
+
+/*!
+ Destroys this event loop locker object
+ */
+QEventLoopLocker::~QEventLoopLocker()
+{
+ delete d_ptr;
+}
+
QT_END_NAMESPACE
diff --git a/src/corelib/kernel/qeventloop.h b/src/corelib/kernel/qeventloop.h
index 3f5cce222f..0e7195d6a7 100644
--- a/src/corelib/kernel/qeventloop.h
+++ b/src/corelib/kernel/qeventloop.h
@@ -80,12 +80,29 @@ public:
void wakeUp();
+ bool event(QEvent *event);
+
public Q_SLOTS:
void quit();
};
Q_DECLARE_OPERATORS_FOR_FLAGS(QEventLoop::ProcessEventsFlags)
+
+class QEventLoopLockerPrivate;
+
+class Q_CORE_EXPORT QEventLoopLocker
+{
+public:
+ QEventLoopLocker();
+ explicit QEventLoopLocker(QEventLoop *loop);
+ ~QEventLoopLocker();
+
+private:
+ Q_DISABLE_COPY(QEventLoopLocker)
+ QEventLoopLockerPrivate *d_ptr;
+};
+
QT_END_NAMESPACE
QT_END_HEADER
diff --git a/src/corelib/kernel/qeventloop_p.h b/src/corelib/kernel/qeventloop_p.h
new file mode 100644
index 0000000000..5770ed0076
--- /dev/null
+++ b/src/corelib/kernel/qeventloop_p.h
@@ -0,0 +1,83 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the QtCore module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** 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, Nokia gives you certain additional
+** rights. These rights are described in the Nokia 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.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef QEVENTLOOP_P_H
+#define QEVENTLOOP_P_H
+
+#include "qobject_p.h"
+
+QT_BEGIN_HEADER
+
+QT_BEGIN_NAMESPACE
+
+QT_MODULE(Core)
+
+class QEventLoopPrivate : public QObjectPrivate
+{
+ Q_DECLARE_PUBLIC(QEventLoop)
+public:
+ inline QEventLoopPrivate()
+ : exit(true), inExec(false), returnCode(-1)
+ { }
+
+ QAtomicInt quitLockRef;
+
+ bool exit, inExec;
+ int returnCode;
+
+ void ref()
+ {
+ quitLockRef.ref();
+ }
+
+ void deref()
+ {
+ if (!quitLockRef.deref() && inExec) {
+ qApp->postEvent(q_ptr, new QEvent(QEvent::Quit));
+ }
+ }
+};
+
+QT_END_NAMESPACE
+
+QT_END_HEADER
+
+#endif // QEVENTLOOP_P_H