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 {
145 bool exceptionCaught;
149 d->exit.storeRelease(
false);
151 auto threadData =
d->threadData.loadRelaxed();
152 ++threadData->loopLevel;
153 threadData->eventLoops.push(
d->q_func());
160 if (exceptionCaught) {
161 qWarning(
"Qt has caught an exception thrown from an event handler. Throwing\n"
162 "exceptions from an event handler is not supported in Qt.\n"
163 "You must not let any exception whatsoever propagate through Qt code.");
166 auto threadData =
d->threadData.loadRelaxed();
167 QEventLoop *eventLoop = threadData->eventLoops.pop();
168 Q_ASSERT_X(eventLoop ==
d->q_func(),
"QEventLoop::exec()",
"internal error");
171 --threadData->loopLevel;
174 LoopReference
ref(
d, locker);
181 while (!
d->exit.loadAcquire())
184 ref.exceptionCaught =
false;
185 return d->returnCode.loadRelaxed();
225 if (!
d->threadData.loadRelaxed()->hasEventDispatcher())
252 auto threadData =
d->threadData.loadAcquire();
253 if (!threadData->hasEventDispatcher())
256 d->returnCode.storeRelaxed(returnCode);
257 d->exit.storeRelease(
true);
258 threadData->eventDispatcher.loadRelaxed()->interrupt();
271 return !
d->exit.loadAcquire();
282 auto threadData =
d->threadData.loadAcquire();
283 if (!threadData->hasEventDispatcher())
285 threadData->eventDispatcher.loadRelaxed()->wakeUp();
314static_assert(
alignof(
QThread) >= 4);
418 visit([](
auto p) {
p->d_func()->deref(); });
427 visit([](
auto p) {
p->d_func()->
ref(); });
433template <
typename Func>
434void QEventLoopLocker::visit(Func
f)
const
441 case Type::Thread:
return f(
static_cast<QThread *
>(
ptr));
449#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.
void unlock() noexcept
Unlocks this mutex locker.
void relock() noexcept
Relocks an unlocked mutex locker.
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.
Combined button and popup list for selecting options.
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]
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent