Qt 4.8
qeventloop.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtCore module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
42 #include "qeventloop.h"
43 
45 #include "qcoreapplication.h"
46 #include "qelapsedtimer.h"
47 
48 #include "qobject_p.h"
49 #include <private/qthread_p.h>
50 
52 
54 {
56 public:
58  : exit(true), inExec(false), returnCode(-1)
59  { }
60  bool exit, inExec;
62 };
63 
118  : QObject(*new QEventLoopPrivate, parent)
119 {
120  Q_D(QEventLoop);
122  qWarning("QEventLoop: Cannot be used without QApplication");
123  } else if (!d->threadData->eventDispatcher) {
125  }
126 }
127 
132 { }
133 
134 
148 bool QEventLoop::processEvents(ProcessEventsFlags flags)
149 {
150  Q_D(QEventLoop);
151  if (!d->threadData->eventDispatcher)
152  return false;
153  if (flags & DeferredDeletion)
155  return d->threadData->eventDispatcher->processEvents(flags);
156 }
157 
181 int QEventLoop::exec(ProcessEventsFlags flags)
182 {
183  Q_D(QEventLoop);
184  //we need to protect from race condition with QThread::exit
185  QMutexLocker locker(&static_cast<QThreadPrivate *>(QObjectPrivate::get(d->threadData->thread))->mutex);
186  if (d->threadData->quitNow)
187  return -1;
188 
189  if (d->inExec) {
190  qWarning("QEventLoop::exec: instance %p has already called exec()", this);
191  return -1;
192  }
193  d->inExec = true;
194  d->exit = false;
195  ++d->threadData->loopLevel;
196  d->threadData->eventLoops.push(this);
197  locker.unlock();
198 
199  // remove posted quit events when entering a new event loop
201  if (app && app->thread() == thread())
203 
204 #if defined(QT_NO_EXCEPTIONS)
205  while (!d->exit)
207 #else
208  try {
209  while (!d->exit)
211  } catch (...) {
212  qWarning("Qt has caught an exception thrown from an event handler. Throwing\n"
213  "exceptions from an event handler is not supported in Qt. You must\n"
214  "reimplement QApplication::notify() and catch all exceptions there.\n");
215 
216  // copied from below
217  locker.relock();
218  QEventLoop *eventLoop = d->threadData->eventLoops.pop();
219  Q_ASSERT_X(eventLoop == this, "QEventLoop::exec()", "internal error");
220  Q_UNUSED(eventLoop); // --release warning
221  d->inExec = false;
222  --d->threadData->loopLevel;
223 
224  throw;
225  }
226 #endif
227 
228  // copied above
229  locker.relock();
230  QEventLoop *eventLoop = d->threadData->eventLoops.pop();
231  Q_ASSERT_X(eventLoop == this, "QEventLoop::exec()", "internal error");
232  Q_UNUSED(eventLoop); // --release warning
233  d->inExec = false;
234  --d->threadData->loopLevel;
235 
236  return d->returnCode;
237 }
238 
255 void QEventLoop::processEvents(ProcessEventsFlags flags, int maxTime)
256 {
257  Q_D(QEventLoop);
258  if (!d->threadData->eventDispatcher)
259  return;
260 
261  QElapsedTimer start;
262  start.start();
263  if (flags & DeferredDeletion)
265  while (processEvents(flags & ~WaitForMoreEvents)) {
266  if (start.elapsed() > maxTime)
267  break;
268  if (flags & DeferredDeletion)
270  }
271 }
272 
288 void QEventLoop::exit(int returnCode)
289 {
290  Q_D(QEventLoop);
291  if (!d->threadData->eventDispatcher)
292  return;
293 
294  d->returnCode = returnCode;
295  d->exit = true;
296  d->threadData->eventDispatcher->interrupt();
297 }
298 
307 {
308  Q_D(const QEventLoop);
309  return !d->exit;
310 }
311 
318 {
319  Q_D(QEventLoop);
320  if (!d->threadData->eventDispatcher)
321  return;
322  d->threadData->eventDispatcher->wakeUp();
323 }
324 
333 { exit(0); }
334 
double d
Definition: qnumeric_p.h:62
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
void unlock()
Unlocks this mutex locker.
Definition: qmutex.h:117
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
#define Q_D(Class)
Definition: qglobal.h:2482
The QElapsedTimer class provides a fast way to calculate elapsed times.
Definition: qelapsedtimer.h:53
static QObjectPrivate * get(QObject *o)
Definition: qobject_p.h:177
qint64 elapsed() const
Returns the number of milliseconds since this QElapsedTimer was last started.
void relock()
Relocks an unlocked mutex locker.
Definition: qmutex.h:125
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
The QEventLoop class provides a means of entering and leaving an event loop.
Definition: qeventloop.h:55
void quit()
Tells the event loop to exit normally.
Definition: qeventloop.cpp:332
Q_CORE_EXPORT void qWarning(const char *,...)
~QEventLoop()
Destroys the event loop object.
Definition: qeventloop.cpp:131
static void sendPostedEvents()
The QCoreApplication class provides an event loop for console Qt applications.
#define Q_ASSERT_X(cond, where, what)
Definition: qglobal.h:1837
void exit(int returnCode=0)
Tells the event loop to exit with a return code.
Definition: qeventloop.cpp:288
The QMutexLocker class is a convenience class that simplifies locking and unlocking mutexes...
Definition: qmutex.h:101
#define Q_DECLARE_PUBLIC(Class)
Definition: qglobal.h:2477
bool isRunning() const
Returns true if the event loop is running; otherwise returns false.
Definition: qeventloop.cpp:306
QEventLoop(QObject *parent=0)
Constructs an event loop object with the given parent.
Definition: qeventloop.cpp:117
static QCoreApplication * instance()
Returns a pointer to the application&#39;s QCoreApplication (or QApplication) instance.
QObject * parent
Definition: qobject.h:92
removePostedEvents
Removes all events of the given eventType that were posted using postEvent() for receiver.
QThread * thread() const
Returns the thread in which the object lives.
Definition: qobject.cpp:1419
static void createEventDispatcher(QThreadData *data)
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
void start()
Starts this timer.
bool processEvents(ProcessEventsFlags flags=AllEvents)
Processes pending events that match flags until there are no more events to process.
Definition: qeventloop.cpp:148
int exec(ProcessEventsFlags flags=AllEvents)
Enters the main event loop and waits until exit() is called.
Definition: qeventloop.cpp:181
void wakeUp()
Wakes up the event loop.
Definition: qeventloop.cpp:317