13#include <private/qthread_p.h>
68 qWarning(
"QEventLoop: Cannot be used without QApplication");
70 d->threadData.loadRelaxed()->ensureEventDispatcher();
97 auto threadData =
d->threadData.loadRelaxed();
98 if (!threadData->hasEventDispatcher())
100 return threadData->eventDispatcher.loadRelaxed()->processEvents(
flags);
129 auto threadData =
d->threadData.loadRelaxed();
133 if (threadData->quitNow)
137 qWarning(
"QEventLoop::exec: instance %p has already called exec()",
this);
141 struct LoopReference {
143 QMutexLocker<QMutex> &locker;
145 bool exceptionCaught;
146 LoopReference(
QEventLoopPrivate *
d, QMutexLocker<QMutex> &locker) :
d(
d), locker(locker), exceptionCaught(
true)
149 d->exit.storeRelease(
false);
151 auto threadData =
d->threadData.loadRelaxed();
152 ++threadData->loopLevel;
153 threadData->eventLoops.push(
d->q_func());
154 qCDebug(lcDeleteLater) <<
"Increased" << threadData->thread
155 <<
"loop level to" << threadData->loopLevel
156 <<
"with leaf loop now" << threadData->eventLoops.last();
163 if (exceptionCaught) {
164 qWarning(
"Qt has caught an exception thrown from an event handler. Throwing\n"
165 "exceptions from an event handler is not supported in Qt.\n"
166 "You must not let any exception whatsoever propagate through Qt code.");
169 auto threadData =
d->threadData.loadRelaxed();
170 QEventLoop *eventLoop = threadData->eventLoops.pop();
171 Q_ASSERT_X(eventLoop ==
d->q_func(),
"QEventLoop::exec()",
"internal error");
174 --threadData->loopLevel;
176 qCDebug(lcDeleteLater) <<
"Decreased" << threadData->thread
177 <<
"loop level to" << threadData->loopLevel
178 <<
"with leaf loop now" << (threadData->eventLoops.isEmpty()
179 ?
nullptr : threadData->eventLoops.last());
183 LoopReference
ref(
d, locker);
190 while (!
d->exit.loadAcquire())
193 ref.exceptionCaught =
false;
194 return d->returnCode.loadRelaxed();
234 if (!
d->threadData.loadRelaxed()->hasEventDispatcher())
261 auto threadData =
d->threadData.loadAcquire();
262 if (!threadData->hasEventDispatcher())
265 d->returnCode.storeRelaxed(returnCode);
266 d->exit.storeRelease(
true);
267 threadData->eventDispatcher.loadRelaxed()->interrupt();
280 return !
d->exit.loadAcquire();
291 auto threadData =
d->threadData.loadAcquire();
292 if (!threadData->hasEventDispatcher())
294 threadData->eventDispatcher.loadRelaxed()->wakeUp();
323static_assert(
alignof(
QThread) >= 4);
430 visit([](
auto p) {
p->d_func()->deref(); });
445template <
typename Func>
446void QEventLoopLocker::visit(Func
f)
const
453 case Type::Thread:
return f(
static_cast<QThread *
>(
ptr));
461#include "moc_qeventloop.cpp"
static bool threadRequiresCoreApplication()
static void removePostedEvents(QObject *receiver, int eventType=0)
static QCoreApplication * instance() noexcept
Returns a pointer to the application's QCoreApplication (or QGuiApplication/QApplication) instance.
bool hasExpired() const noexcept
Returns true if this QDeadlineTimer object has expired, false if there remains time left.
Q_NODISCARD_CTOR Q_CORE_EXPORT QEventLoopLocker() noexcept
Creates an event locker operating on the QCoreApplication.
Q_CORE_EXPORT ~QEventLoopLocker()
Destroys this event loop locker object.
int exec(ProcessEventsFlags flags=AllEvents)
Enters the main event loop and waits until exit() is called.
~QEventLoop()
Destroys the event loop object.
void exit(int returnCode=0)
Tells the event loop to exit with a return code.
bool isRunning() const
Returns true if the event loop is running; otherwise returns false.
bool processEvents(ProcessEventsFlags flags=AllEvents)
Processes some pending events that match flags.
bool event(QEvent *event) override
\reimp
void wakeUp()
Wakes up the event loop.
QEventLoop(QObject *parent=nullptr)
Constructs an event loop object with the given parent.
void quit()
Tells the event loop to exit normally.
static QObjectPrivate * get(QObject *o)
virtual bool event(QEvent *event)
This virtual function receives events to an object and should return true if the event e was recogniz...
QThread * thread() const
Returns the thread in which the object lives.
auto visit(Fn &&fn, QIODevice *socket, Args &&...args)
Combined button and popup list for selecting options.
#define qCDebug(category,...)
static ControlElement< T > * ptr(QWidget *widget)
GLsizei const void * pointer
#define Q_ASSERT_X(cond, x, msg)
QDeadlineTimer deadline(30s)
QApplication app(argc, argv)
[0]