66QEventLoop::QEventLoop(QObject *parent)
67 : QObject(*
new QEventLoopPrivate, parent)
70 QThreadData *threadData = d->threadData.loadRelaxed();
71 if (!QCoreApplication::instanceExists() && threadData->requiresCoreApplication) {
72 qWarning(
"QEventLoop: Cannot be used without QCoreApplication");
74 threadData->ensureEventDispatcher();
130int QEventLoop::exec(ProcessEventsFlags flags)
133 auto threadData = d->threadData.loadRelaxed();
136 QMutexLocker locker(&
static_cast<QThreadPrivate *>(QObjectPrivate::get(threadData->thread.loadAcquire()))->mutex);
137 if (threadData->quitNow)
141 qWarning(
"QEventLoop::exec: instance %p has already called exec()",
this);
145 struct LoopReference {
146 QEventLoopPrivate *d;
147 QMutexLocker<QMutex> &locker;
149 bool exceptionCaught;
150 LoopReference(QEventLoopPrivate *d, QMutexLocker<QMutex> &locker) : d(d), locker(locker), exceptionCaught(
true)
153 d->exit.storeRelease(
false);
155 auto threadData = d->threadData.loadRelaxed();
156 ++threadData->loopLevel;
157 threadData->eventLoops.push(d->q_func());
164 if (exceptionCaught) {
165 qWarning(
"Qt has caught an exception thrown from an event handler. Throwing\n"
166 "exceptions from an event handler is not supported in Qt.\n"
167 "You must not let any exception whatsoever propagate through Qt code.");
170 auto threadData = d->threadData.loadRelaxed();
171 QEventLoop *eventLoop = threadData->eventLoops.pop();
172 Q_ASSERT_X(eventLoop == d->q_func(),
"QEventLoop::exec()",
"internal error");
175 --threadData->loopLevel;
178 LoopReference ref(d, locker);
181 QCoreApplication *app = QCoreApplication::instance();
182 if (app && app->thread() == thread())
183 QCoreApplication::removePostedEvents(app, QEvent::Quit);
185 while (!d->exit.loadAcquire())
186 processEvents(flags | WaitForMoreEvents | EventLoopExec);
188 ref.exceptionCaught =
false;
189 return d->returnCode.loadRelaxed();