1// Copyright (C) 2016 The Qt Company Ltd.
2// Copyright (C) 2016 Intel Corporation.
3// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
4
5#include "qthread.h"
6#include "qthreadstorage.h"
7#include "qmutex.h"
8#include "qreadwritelock.h"
9#include "qabstracteventdispatcher.h"
10#include "qbindingstorage.h"
11
12#include <qeventloop.h>
13
14#include "qthread_p.h"
15#include "private/qcoreapplication_p.h"
16
17#include <limits>
18
19QT_BEGIN_NAMESPACE
20
21/*
22 QPostEventList
23*/
24
25void QPostEventList::addEvent(const QPostEvent &ev)
26{
27 int priority = ev.priority;
28 if (isEmpty() ||
29 constLast().priority >= priority ||
30 insertionOffset >= size()) {
31 // optimization: we can simply append if the last event in
32 // the queue has higher or equal priority
33 append(t: ev);
34 } else {
35 // insert event in descending priority order, using upper
36 // bound for a given priority (to ensure proper ordering
37 // of events with the same priority)
38 QPostEventList::iterator at = std::upper_bound(first: begin() + insertionOffset, last: end(), val: ev);
39 insert(before: at, t: ev);
40 }
41}
42
43
44/*
45 QThreadData
46*/
47
48QThreadData::QThreadData(int initialRefCount)
49 : _ref(initialRefCount), loopLevel(0), scopeLevel(0),
50 eventDispatcher(nullptr),
51 quitNow(false), canWait(true), isAdopted(false), requiresCoreApplication(true)
52{
53 // fprintf(stderr, "QThreadData %p created\n", this);
54}
55
56QThreadData::~QThreadData()
57{
58#if QT_CONFIG(thread)
59 Q_ASSERT(_ref.loadRelaxed() == 0);
60#endif
61
62 // In the odd case that Qt is running on a secondary thread, the main
63 // thread instance will have been dereffed asunder because of the deref in
64 // QThreadData::current() and the deref in the pthread_destroy. To avoid
65 // crashing during QCoreApplicationData's global static cleanup we need to
66 // safeguard the main thread here.. This fix is a bit crude, but it solves
67 // the problem...
68 if (threadId.loadAcquire() == QCoreApplicationPrivate::theMainThreadId.loadAcquire()) {
69 QCoreApplicationPrivate::theMainThread.storeRelease(newValue: nullptr);
70 QCoreApplicationPrivate::theMainThreadId.storeRelaxed(newValue: nullptr);
71 QThreadData::clearCurrentThreadData();
72 }
73
74 // ~QThread() sets thread to nullptr, so if it isn't null here, it's
75 // because we're being run before the main object itself. This can only
76 // happen for QAdoptedThread. Note that both ~QThreadPrivate() and
77 // ~QObjectPrivate() will deref this object again, but that is acceptable
78 // because this destructor is still running (the _ref sub-object has not
79 // been destroyed) and there's no reentrancy. The refcount will become
80 // negative, but that's acceptable.
81 QThread *t = thread.loadAcquire();
82 thread.storeRelease(newValue: nullptr);
83 delete t;
84
85 for (qsizetype i = 0; i < postEventList.size(); ++i) {
86 const QPostEvent &pe = postEventList.at(i);
87 if (pe.event) {
88 pe.receiver->d_func()->postedEvents.fetchAndSubRelaxed(valueToAdd: 1);
89 pe.event->m_posted = false;
90 delete pe.event;
91 }
92 }
93
94 // fprintf(stderr, "QThreadData %p destroyed\n", this);
95}
96
97QAbstractEventDispatcher *QThreadData::createEventDispatcher()
98{
99 QAbstractEventDispatcher *ed = QThreadPrivate::createEventDispatcher(data: this);
100 eventDispatcher.storeRelease(newValue: ed);
101 return ed;
102}
103
104/*
105 QAdoptedThread
106*/
107
108QAdoptedThread::QAdoptedThread(QThreadData *data)
109 : QThread(*new QThreadPrivate(data))
110{
111 // thread should be running and not finished for the lifetime
112 // of the application (even if QCoreApplication goes away)
113#if QT_CONFIG(thread)
114 d_func()->running = true;
115 d_func()->finished = false;
116 init();
117 d_func()->m_statusOrPendingObjects.setStatusAndClearList(
118 QtPrivate::getBindingStatus({}));
119#endif
120 // fprintf(stderr, "new QAdoptedThread = %p\n", this);
121}
122
123QAdoptedThread::~QAdoptedThread()
124{
125 // fprintf(stderr, "~QAdoptedThread = %p\n", this);
126}
127
128#if QT_CONFIG(thread)
129void QAdoptedThread::run()
130{
131 // this function should never be called
132 qFatal(msg: "QAdoptedThread::run(): Internal error, this implementation should never be called.");
133}
134#endif
135
136#if QT_CONFIG(thread)
137/*
138 QThreadPrivate
139*/
140
141QThreadPrivate::QThreadPrivate(QThreadData *d)
142 : QObjectPrivate(), running(false), finished(false),
143 isInFinish(false), interruptionRequested(false),
144 exited(false), returnCode(-1),
145 stackSize(0), priority(QThread::InheritPriority), data(d)
146{
147
148// INTEGRITY doesn't support self-extending stack. The default stack size for
149// a pthread on INTEGRITY is too small so we have to increase the default size
150// to 128K.
151#ifdef Q_OS_INTEGRITY
152 stackSize = 128 * 1024;
153#elif defined(Q_OS_RTEMS)
154 Q_CONSTINIT static bool envStackSizeOk = false;
155 static const int envStackSize = qEnvironmentVariableIntValue("QT_DEFAULT_THREAD_STACK_SIZE", &envStackSizeOk);
156 if (envStackSizeOk)
157 stackSize = envStackSize;
158#endif
159
160#if defined (Q_OS_WIN)
161 handle = 0;
162 id = 0;
163 waiters = 0;
164 terminationEnabled = true;
165 terminatePending = false;
166#endif
167
168 if (!data)
169 data = new QThreadData;
170}
171
172QThreadPrivate::~QThreadPrivate()
173{
174 // access to m_statusOrPendingObjects cannot race with anything
175 // unless there is already a potential use-after-free bug, as the
176 // thread is in the process of being destroyed
177 delete m_statusOrPendingObjects.list();
178 data->deref();
179}
180
181/*!
182 \class QThread
183 \inmodule QtCore
184 \brief The QThread class provides a platform-independent way to
185 manage threads.
186
187 \ingroup thread
188
189 A QThread object manages one thread of control within the
190 program. QThreads begin executing in run(). By default, run() starts the
191 event loop by calling exec() and runs a Qt event loop inside the thread.
192
193 You can use worker objects by moving them to the thread using
194 QObject::moveToThread().
195
196 \snippet code/src_corelib_thread_qthread.cpp worker
197
198 The code inside the Worker's slot would then execute in a
199 separate thread. However, you are free to connect the
200 Worker's slots to any signal, from any object, in any thread. It
201 is safe to connect signals and slots across different threads,
202 thanks to a mechanism called \l{Qt::QueuedConnection}{queued
203 connections}.
204
205 Another way to make code run in a separate thread, is to subclass QThread
206 and reimplement run(). For example:
207
208 \snippet code/src_corelib_thread_qthread.cpp reimpl-run
209
210 In that example, the thread will exit after the run function has returned.
211 There will not be any event loop running in the thread unless you call
212 exec().
213
214 It is important to remember that a QThread instance \l{QObject#Thread
215 Affinity}{lives in} the old thread that instantiated it, not in the
216 new thread that calls run(). This means that all of QThread's queued
217 slots and \l {QMetaObject::invokeMethod()}{invoked methods} will execute
218 in the old thread. Thus, a developer who wishes to invoke slots in the
219 new thread must use the worker-object approach; new slots should not be
220 implemented directly into a subclassed QThread.
221
222 Unlike queued slots or invoked methods, methods called directly on the
223 QThread object will execute in the thread that calls the method. When
224 subclassing QThread, keep in mind that the constructor executes in the
225 old thread while run() executes in the new thread. If a member variable
226 is accessed from both functions, then the variable is accessed from two
227 different threads. Check that it is safe to do so.
228
229 \note Care must be taken when interacting with objects across different
230 threads. As a general rule, functions can only be called from the thread
231 that created the QThread object itself (e.g. setPriority()), unless the
232 documentation says otherwise. See \l{Synchronizing Threads} for details.
233
234 \section1 Managing Threads
235
236 QThread will notify you via a signal when the thread is
237 started() and finished(), or you can use isFinished() and
238 isRunning() to query the state of the thread.
239
240 You can stop the thread by calling exit() or quit(). In extreme
241 cases, you may want to forcibly terminate() an executing thread.
242 However, doing so is dangerous and discouraged. Please read the
243 documentation for terminate() and setTerminationEnabled() for
244 detailed information.
245
246 You often want to deallocate objects that live in a thread when
247 a thread ends. To do this, connect the finished() signal to
248 QObject::deleteLater().
249
250 Use wait() to block the calling thread, until the other thread
251 has finished execution (or until a specified time has passed).
252
253 QThread also provides static, platform independent sleep
254 functions: sleep(), msleep(), and usleep() allow full second,
255 millisecond, and microsecond resolution respectively.
256
257 \note wait() and the sleep() functions should be unnecessary in
258 general, since Qt is an event-driven framework. Instead of
259 wait(), consider listening for the finished() signal. Instead of
260 the sleep() functions, consider using QChronoTimer.
261
262 The static functions currentThreadId() and currentThread() return
263 identifiers for the currently executing thread. The former
264 returns a platform specific ID for the thread; the latter returns
265 a QThread pointer.
266
267 To choose the name that your thread will be given (as identified
268 by the command \c{ps -L} on Linux, for example), you can call
269 \l{QObject::setObjectName()}{setObjectName()} before starting the thread.
270 If you don't call \l{QObject::setObjectName()}{setObjectName()},
271 the name given to your thread will be the class name of the runtime
272 type of your thread object (for example, \c "RenderThread" in the case of the
273 \l{Mandelbrot} example, as that is the name of the QThread subclass).
274 Note that this is currently not available with release builds on Windows.
275
276 \sa {Thread Support in Qt}, QThreadStorage, {Synchronizing Threads},
277 Mandelbrot, {Producer and Consumer using Semaphores},
278 {Producer and Consumer using Wait Conditions}
279*/
280
281/*!
282 \fn Qt::HANDLE QThread::currentThreadId()
283
284 Returns the thread handle of the currently executing thread.
285
286 \warning The handle returned by this function is used for internal
287 purposes and should not be used in any application code.
288
289 \note On Windows, this function returns the DWORD (Windows-Thread
290 ID) returned by the Win32 function GetCurrentThreadId(), not the pseudo-HANDLE
291 (Windows-Thread HANDLE) returned by the Win32 function GetCurrentThread().
292*/
293
294/*!
295 \fn int QThread::idealThreadCount()
296
297 Returns the ideal number of threads that this process can run in parallel.
298 This is done by querying the number of logical processors available to this
299 process (if supported by this OS) or the total number of logical processors
300 in the system. This function returns 1 if neither value could be
301 determined.
302
303 \note On operating systems that support setting a thread's affinity to a
304 subset of all logical processors, the value returned by this function may
305 change between threads and over time.
306
307 \note On operating systems that support CPU hotplugging and hot-unplugging,
308 the value returned by this function may also change over time (and note
309 that CPUs can be turned on and off by software, without a physical,
310 hardware change).
311*/
312
313/*!
314 \fn void QThread::yieldCurrentThread()
315
316 Yields execution of the current thread to another runnable thread,
317 if any. Note that the operating system decides to which thread to
318 switch.
319*/
320
321/*!
322 \fn void QThread::start(Priority priority)
323
324 Begins execution of the thread by calling run(). The
325 operating system will schedule the thread according to the \a
326 priority parameter. If the thread is already running, this
327 function does nothing.
328
329 The effect of the \a priority parameter is dependent on the
330 operating system's scheduling policy. In particular, the \a priority
331 will be ignored on systems that do not support thread priorities
332 (such as on Linux, see the
333 \l {http://linux.die.net/man/2/sched_setscheduler}{sched_setscheduler}
334 documentation for more details).
335
336 \sa run(), terminate()
337*/
338
339/*!
340 \fn void QThread::started()
341
342 This signal is emitted from the associated thread when it starts executing,
343 so any slots connected to it may be called via queued invocation. Whilst
344 the event may have been posted before run() is called, any
345 \l {Signals and Slots Across Threads} {cross-thread delivery} of the signal
346 may still be pending.
347
348 \sa run(), finished()
349*/
350
351/*!
352 \fn void QThread::finished()
353
354 This signal is emitted from the associated thread right before it finishes executing.
355
356 When this signal is emitted, the event loop has already stopped running.
357 No more events will be processed in the thread, except for deferred deletion events.
358 This signal can be connected to QObject::deleteLater(), to free objects in that thread.
359
360 \note If the associated thread was terminated using terminate(), it is undefined from
361 which thread this signal is emitted.
362
363 \sa started()
364*/
365
366/*!
367 \enum QThread::Priority
368
369 This enum type indicates how the operating system should schedule
370 newly created threads.
371
372 \value IdlePriority scheduled only when no other threads are
373 running.
374
375 \value LowestPriority scheduled less often than LowPriority.
376 \value LowPriority scheduled less often than NormalPriority.
377
378 \value NormalPriority the default priority of the operating
379 system.
380
381 \value HighPriority scheduled more often than NormalPriority.
382 \value HighestPriority scheduled more often than HighPriority.
383
384 \value TimeCriticalPriority scheduled as often as possible.
385
386 \value InheritPriority use the same priority as the creating
387 thread. This is the default.
388*/
389
390/*!
391 Returns a pointer to a QThread which manages the currently
392 executing thread.
393*/
394QThread *QThread::currentThread()
395{
396 QThreadData *data = QThreadData::current();
397 Q_ASSERT(data != nullptr);
398 return data->thread.loadAcquire();
399}
400
401/*!
402 \since 6.8
403
404 Returns whether the currently executing thread is the main thread.
405
406 The main thread is the thread in which QCoreApplication was created.
407 This is usually the thread that called the \c{main()} function, but not necessarily so.
408 It is the thread that is processing the GUI events and in which graphical objects
409 (QWindow, QWidget) can be created.
410
411 \sa currentThread(), QCoreApplication::instance()
412*/
413bool QThread::isMainThread() noexcept
414{
415 return currentThreadId() == QCoreApplicationPrivate::theMainThreadId.loadRelaxed();
416}
417
418/*!
419 Constructs a new QThread to manage a new thread. The \a parent
420 takes ownership of the QThread. The thread does not begin
421 executing until start() is called.
422
423 \sa start()
424*/
425QThread::QThread(QObject *parent)
426 : QObject(*(new QThreadPrivate), parent)
427{
428 Q_D(QThread);
429 // fprintf(stderr, "QThreadData %p created for thread %p\n", d->data, this);
430 d->data->thread.storeRelaxed(newValue: this);
431}
432
433/*!
434 \internal
435 */
436QThread::QThread(QThreadPrivate &dd, QObject *parent)
437 : QObject(dd, parent)
438{
439 Q_D(QThread);
440 // fprintf(stderr, "QThreadData %p taken from private data for thread %p\n", d->data, this);
441 d->data->thread.storeRelaxed(newValue: this);
442}
443
444/*!
445 Destroys the QThread.
446
447 Note that deleting a QThread object will not stop the execution
448 of the thread it manages. Deleting a running QThread (i.e.
449 isFinished() returns \c false) will result in a program
450 crash. Wait for the finished() signal before deleting the
451 QThread.
452
453 Since Qt 6.3, it is allowed to delete a QThread instance created by
454 a call to QThread::create() even if the corresponding thread is
455 still running. In such a case, Qt will post an interruption request
456 to that thread (via requestInterruption()); will ask the thread's
457 event loop (if any) to quit (via quit()); and will block until the
458 thread has finished.
459
460 \sa create(), isInterruptionRequested(), exec(), quit()
461*/
462QThread::~QThread()
463{
464 Q_D(QThread);
465 {
466 QMutexLocker locker(&d->mutex);
467 if (d->isInFinish)
468 d->wait(locker, deadline: QDeadlineTimer::Forever);
469 if (d->running && !d->finished && !d->data->isAdopted)
470 qFatal(msg: "QThread: Destroyed while thread is still running");
471
472 d->data->thread.storeRelease(newValue: nullptr);
473 }
474}
475
476/*!
477 \threadsafe
478 Returns \c true if the thread is finished; otherwise returns \c false.
479
480 \sa isRunning()
481*/
482bool QThread::isFinished() const
483{
484 Q_D(const QThread);
485 QMutexLocker locker(&d->mutex);
486 return d->finished || d->isInFinish;
487}
488
489/*!
490 \threadsafe
491 Returns \c true if the thread is running; otherwise returns \c false.
492
493 \sa isFinished()
494*/
495bool QThread::isRunning() const
496{
497 Q_D(const QThread);
498 QMutexLocker locker(&d->mutex);
499 return d->running && !d->isInFinish;
500}
501
502/*!
503 Sets the stack size for the thread to \a stackSize. If \a stackSize is
504 zero, the operating system or runtime will choose a default value.
505 Otherwise, the thread's stack size will be the value provided (which may be
506 rounded up or down).
507
508 On most operating systems, the amount of memory allocated to serve the
509 stack will initially be smaller than \a stackSize and will grow as the
510 thread uses the stack. This parameter sets the maximum size it will be
511 allowed to grow to (that is, it sets the size of the virtual memory space
512 the stack is allowed to occupy).
513
514 This function can only be called before the thread is started.
515
516 \warning Most operating systems place minimum and maximum limits
517 on thread stack sizes. The thread will fail to start if the stack
518 size is outside these limits.
519
520 \sa stackSize()
521*/
522void QThread::setStackSize(uint stackSize)
523{
524 Q_D(QThread);
525 QMutexLocker locker(&d->mutex);
526 Q_ASSERT_X(!d->running, "QThread::setStackSize",
527 "cannot change stack size while the thread is running");
528 d->stackSize = stackSize;
529}
530
531/*!
532 Returns the maximum stack size for the thread (if set with
533 setStackSize()); otherwise returns zero.
534
535 \sa setStackSize()
536*/
537uint QThread::stackSize() const
538{
539 Q_D(const QThread);
540 QMutexLocker locker(&d->mutex);
541 return d->stackSize;
542}
543
544/*!
545 \internal
546 Transitions BindingStatusOrList to the binding status state. If we had a list of
547 pending objects, all objects get their reinitBindingStorageAfterThreadMove method
548 called, and afterwards, the list gets discarded.
549 */
550void QtPrivate::BindingStatusOrList::setStatusAndClearList(QBindingStatus *status) noexcept
551{
552
553 if (auto pendingObjects = list()) {
554 for (auto obj: *pendingObjects)
555 QObjectPrivate::get(o: obj)->reinitBindingStorageAfterThreadMove();
556 delete pendingObjects;
557 }
558 // synchronizes-with the load-acquire in bindingStatus():
559 data.store(i: encodeBindingStatus(status), m: std::memory_order_release);
560}
561
562/*!
563 Enters the event loop and waits until exit() is called, returning the value
564 that was passed to exit(). The value returned is 0 if exit() is called via
565 quit().
566
567 This function is meant to be called from within run(). It is necessary to
568 call this function to start event handling.
569
570 \note This can only be called within the thread itself, i.e. when
571 it is the current thread.
572
573 \sa quit(), exit()
574*/
575int QThread::exec()
576{
577 Q_D(QThread);
578 const auto status = QtPrivate::getBindingStatus(QtPrivate::QBindingStatusAccessToken{});
579
580 QMutexLocker locker(&d->mutex);
581 d->m_statusOrPendingObjects.setStatusAndClearList(status);
582 d->data->quitNow = false;
583 if (d->exited) {
584 d->exited = false;
585 return d->returnCode;
586 }
587 locker.unlock();
588
589 QEventLoop eventLoop;
590 int returnCode = eventLoop.exec();
591
592 locker.relock();
593 d->exited = false;
594 d->returnCode = -1;
595 return returnCode;
596}
597
598
599/*!
600 \internal
601 If BindingStatusOrList is already in the binding status state, this will
602 return that BindingStatus pointer.
603 Otherwise, \a object is added to the list, and we return nullptr.
604 The list is allocated if it does not already exist.
605 */
606QBindingStatus *QtPrivate::BindingStatusOrList::addObjectUnlessAlreadyStatus(QObject *object)
607{
608 if (auto status = bindingStatus())
609 return status;
610 List *objectList = list();
611 if (!objectList) {
612 objectList = new List();
613 objectList->reserve(n: 8);
614 data.store(i: encodeList(list: objectList), m: std::memory_order_relaxed);
615 }
616 objectList->push_back(x: object);
617 return nullptr;
618}
619
620/*!
621 \internal
622 If BindingStatusOrList is a list, remove \a object from it
623 */
624void QtPrivate::BindingStatusOrList::removeObject(QObject *object)
625{
626 List *objectList = list();
627 if (!objectList)
628 return;
629 auto it = std::remove(first: objectList->begin(), last: objectList->end(), value: object);
630 objectList->erase(first: it, last: objectList->end());
631}
632
633QBindingStatus *QThreadPrivate::addObjectWithPendingBindingStatusChange(QObject *obj)
634{
635 if (auto status = m_statusOrPendingObjects.bindingStatus())
636 return status;
637 QMutexLocker lock(&mutex);
638 return m_statusOrPendingObjects.addObjectUnlessAlreadyStatus(object: obj);
639}
640
641void QThreadPrivate::removeObjectWithPendingBindingStatusChange(QObject *obj)
642{
643 if (m_statusOrPendingObjects.bindingStatus())
644 return;
645 QMutexLocker lock(&mutex);
646 m_statusOrPendingObjects.removeObject(object: obj);
647}
648
649
650/*!
651 \threadsafe
652 Tells the thread's event loop to exit with a return code.
653
654 After calling this function, the thread leaves the event loop and
655 returns from the call to QEventLoop::exec(). The
656 QEventLoop::exec() function returns \a returnCode.
657
658 By convention, a \a returnCode of 0 means success, any non-zero value
659 indicates an error.
660
661 Note that unlike the C library function of the same name, this
662 function \e does return to the caller -- it is event processing
663 that stops.
664
665 No QEventLoops will be started anymore in this thread until
666 QThread::exec() has been called again. If the eventloop in QThread::exec()
667 is not running then the next call to QThread::exec() will also return
668 immediately.
669
670 \sa quit(), QEventLoop
671*/
672void QThread::exit(int returnCode)
673{
674 Q_D(QThread);
675 QMutexLocker locker(&d->mutex);
676 d->exited = true;
677 d->returnCode = returnCode;
678 d->data->quitNow = true;
679 for (int i = 0; i < d->data->eventLoops.size(); ++i) {
680 QEventLoop *eventLoop = d->data->eventLoops.at(i);
681 eventLoop->exit(returnCode);
682 }
683}
684
685/*!
686 \threadsafe
687 Tells the thread's event loop to exit with return code 0 (success).
688 Equivalent to calling QThread::exit(0).
689
690 This function does nothing if the thread does not have an event
691 loop.
692
693 \sa exit(), QEventLoop
694*/
695void QThread::quit()
696{ exit(); }
697
698/*!
699 The starting point for the thread. After calling start(), the
700 newly created thread calls this function. The default
701 implementation simply calls exec().
702
703 You can reimplement this function to facilitate advanced thread
704 management. Returning from this method will end the execution of
705 the thread.
706
707 \sa start(), wait()
708*/
709void QThread::run()
710{
711 (void) exec();
712}
713
714/*! \fn void QThread::setPriority(Priority priority)
715 \since 4.1
716
717 This function sets the \a priority for a running thread. If the
718 thread is not running, this function does nothing and returns
719 immediately. Use start() to start a thread with a specific
720 priority.
721
722 The \a priority argument can be any value in the \c
723 QThread::Priority enum except for \c InheritPriority.
724
725 The effect of the \a priority parameter is dependent on the
726 operating system's scheduling policy. In particular, the \a priority
727 will be ignored on systems that do not support thread priorities
728 (such as on Linux, see http://linux.die.net/man/2/sched_setscheduler
729 for more details).
730
731 \sa Priority, priority(), start()
732*/
733void QThread::setPriority(Priority priority)
734{
735 if (priority == QThread::InheritPriority) {
736 qWarning(msg: "QThread::setPriority: Argument cannot be InheritPriority");
737 return;
738 }
739 Q_D(QThread);
740 QMutexLocker locker(&d->mutex);
741 if (!d->running) {
742 qWarning(msg: "QThread::setPriority: Cannot set priority, thread is not running");
743 return;
744 }
745 d->setPriority(priority);
746}
747
748/*!
749 \since 4.1
750
751 Returns the priority for a running thread. If the thread is not
752 running, this function returns \c InheritPriority.
753
754 \sa Priority, setPriority(), start()
755*/
756QThread::Priority QThread::priority() const
757{
758 Q_D(const QThread);
759 QMutexLocker locker(&d->mutex);
760
761 // mask off the high bits that are used for flags
762 return Priority(d->priority & 0xffff);
763}
764
765/*!
766 \fn void QThread::sleep(std::chrono::nanoseconds nsecs)
767 \since 6.6
768
769 Forces the current thread to sleep for \a nsecs.
770
771 Avoid using this function if you need to wait for a given condition to
772 change. Instead, connect a slot to the signal that indicates the change or
773 use an event handler (see \l QObject::event()).
774
775 \note This function does not guarantee accuracy. The application may sleep
776 longer than \a nsecs under heavy load conditions.
777*/
778
779/*!
780 \fn void QThread::sleep(unsigned long secs)
781
782 Forces the current thread to sleep for \a secs seconds.
783
784 This is an overloaded function, equivalent to calling:
785 \code
786 QThread::sleep(std::chrono::seconds{secs});
787 \endcode
788
789 \sa msleep(), usleep()
790*/
791
792/*!
793 \fn void QThread::msleep(unsigned long msecs)
794
795 This is an overloaded function, equivalent to calling:
796 \code
797 QThread::sleep(std::chrono::milliseconds{msecs});
798 \endcode
799
800 \note This function does not guarantee accuracy. The application may sleep
801 longer than \a msecs under heavy load conditions. Some OSes might round \a
802 msecs up to 10 ms or 15 ms.
803
804 \sa sleep(), usleep()
805*/
806
807/*!
808 \fn void QThread::usleep(unsigned long usecs)
809
810 This is an overloaded function, equivalent to calling:
811 \code
812 QThread::sleep(std::chrono::microseconds{secs});
813 \endcode
814
815 \note This function does not guarantee accuracy. The application may sleep
816 longer than \a usecs under heavy load conditions. Some OSes might round \a
817 usecs up to 10 ms or 15 ms; on Windows, it will be rounded up to a multiple
818 of 1 ms.
819
820 \sa sleep(), msleep()
821*/
822
823/*!
824 \fn void QThread::terminate()
825 \threadsafe
826
827 Terminates the execution of the thread. The thread may or may not
828 be terminated immediately, depending on the operating system's
829 scheduling policies. Use QThread::wait() after terminate(), to be
830 sure.
831
832 When the thread is terminated, all threads waiting for the thread
833 to finish will be woken up.
834
835 \warning This function is dangerous and its use is discouraged.
836 The thread can be terminated at any point in its code path.
837 Threads can be terminated while modifying data. There is no
838 chance for the thread to clean up after itself, unlock any held
839 mutexes, etc. In short, use this function only if absolutely
840 necessary.
841
842 Termination can be explicitly enabled or disabled by calling
843 QThread::setTerminationEnabled(). Calling this function while
844 termination is disabled results in the termination being
845 deferred, until termination is re-enabled. See the documentation
846 of QThread::setTerminationEnabled() for more information.
847
848 \sa setTerminationEnabled()
849*/
850
851/*!
852 \fn bool QThread::wait(QDeadlineTimer deadline)
853 \since 5.15
854
855 Blocks the thread until either of these conditions is met:
856
857 \list
858 \li The thread associated with this QThread object has finished
859 execution (i.e. when it returns from \l{run()}). This function
860 will return true if the thread has finished. It also returns
861 true if the thread has not been started yet.
862 \li The \a deadline is reached. This function will return false if the
863 deadline is reached.
864 \endlist
865
866 A deadline timer set to \c QDeadlineTimer::Forever (the default) will never
867 time out: in this case, the function only returns when the thread returns
868 from \l{run()} or if the thread has not yet started.
869
870 This provides similar functionality to the POSIX \c
871 pthread_join() function.
872
873 \sa sleep(), terminate()
874*/
875
876/*!
877 \fn void QThread::setTerminationEnabled(bool enabled)
878
879 Enables or disables termination of the current thread based on the
880 \a enabled parameter. The thread must have been started by
881 QThread.
882
883 When \a enabled is false, termination is disabled. Future calls
884 to QThread::terminate() will return immediately without effect.
885 Instead, the termination is deferred until termination is enabled.
886
887 When \a enabled is true, termination is enabled. Future calls to
888 QThread::terminate() will terminate the thread normally. If
889 termination has been deferred (i.e. QThread::terminate() was
890 called with termination disabled), this function will terminate
891 the calling thread \e immediately. Note that this function will
892 not return in this case.
893
894 \sa terminate()
895*/
896
897/*!
898 \since 5.5
899 Returns the current event loop level for the thread.
900
901 \note This can only be called within the thread itself, i.e. when
902 it is the current thread.
903*/
904
905int QThread::loopLevel() const
906{
907 Q_D(const QThread);
908 return d->data->eventLoops.size();
909}
910
911/*!
912 \internal
913 Returns the thread handle of this thread.
914 It can be compared with the return value of currentThreadId().
915
916 This is used to implement isCurrentThread, and might be useful
917 for debugging (e.g. by comparing the value in gdb with info threads).
918
919 \note Thread handles of destroyed threads might be reused by the
920 operating system. Storing the return value of this function can
921 therefore give surprising results if it outlives the QThread object
922 (threads claimed to be the same even if they aren't).
923*/
924Qt::HANDLE QThreadPrivate::threadId() const noexcept
925{
926 return data->threadId.loadRelaxed();
927}
928
929/*!
930 \since 6.8
931 Returns true if this thread is QThread::currentThread.
932
933 \sa currentThreadId()
934*/
935bool QThread::isCurrentThread() const noexcept
936{
937 Q_D(const QThread);
938 return QThread::currentThreadId() == d->threadId();
939}
940
941#else // QT_CONFIG(thread)
942
943QThread::QThread(QObject *parent)
944 : QObject(*(new QThreadPrivate), parent)
945{
946 Q_D(QThread);
947 d->data->thread.storeRelaxed(this);
948}
949
950QThread::~QThread()
951{
952
953}
954
955void QThread::run()
956{
957
958}
959
960int QThread::exec()
961{
962 return 0;
963}
964
965void QThread::start(Priority priority)
966{
967 Q_D(QThread);
968 Q_UNUSED(priority);
969 d->running = true;
970}
971
972void QThread::terminate()
973{
974
975}
976
977void QThread::quit()
978{
979
980}
981
982void QThread::exit(int returnCode)
983{
984 Q_D(QThread);
985 d->data->quitNow = true;
986 for (int i = 0; i < d->data->eventLoops.size(); ++i) {
987 QEventLoop *eventLoop = d->data->eventLoops.at(i);
988 eventLoop->exit(returnCode);
989 }
990}
991
992bool QThread::wait(QDeadlineTimer deadline)
993{
994 Q_UNUSED(deadline);
995 return false;
996}
997
998bool QThread::event(QEvent *event)
999{
1000 return QObject::event(event);
1001}
1002
1003Qt::HANDLE QThread::currentThreadIdImpl() noexcept
1004{
1005 return Qt::HANDLE(currentThread());
1006}
1007
1008QThread *QThread::currentThread()
1009{
1010 return QThreadData::current()->thread.loadAcquire();
1011}
1012
1013bool QThread::isMainThread() noexcept
1014{
1015 return true;
1016}
1017
1018bool QThread::isCurrentThread() const noexcept
1019{
1020 return true;
1021}
1022
1023int QThread::idealThreadCount() noexcept
1024{
1025 return 1;
1026}
1027
1028void QThread::yieldCurrentThread()
1029{
1030
1031}
1032
1033bool QThread::isFinished() const
1034{
1035 return false;
1036}
1037
1038bool QThread::isRunning() const
1039{
1040 Q_D(const QThread);
1041 return d->running;
1042}
1043
1044void QThread::requestInterruption()
1045{
1046
1047}
1048
1049bool QThread::isInterruptionRequested() const
1050{
1051 return false;
1052}
1053
1054void QThread::setTerminationEnabled(bool)
1055{
1056}
1057
1058// No threads: so we can just use static variables
1059Q_CONSTINIT static QThreadData *data = nullptr;
1060
1061QThreadData *QThreadData::current(bool createIfNecessary)
1062{
1063 if (!data && createIfNecessary) {
1064 data = new QThreadData;
1065 data->thread = new QAdoptedThread(data);
1066 data->threadId.storeRelaxed(Qt::HANDLE(data->thread.loadAcquire()));
1067 data->deref();
1068 data->isAdopted = true;
1069 if (!QCoreApplicationPrivate::theMainThreadId.loadAcquire()) {
1070 auto *mainThread = data->thread.loadRelaxed();
1071 mainThread->setObjectName("Qt mainThread");
1072 QCoreApplicationPrivate::theMainThread.storeRelease(mainThread);
1073 QCoreApplicationPrivate::theMainThreadId.storeRelaxed(data->threadId.loadRelaxed());
1074 }
1075 }
1076 return data;
1077}
1078
1079void QThreadData::clearCurrentThreadData()
1080{
1081 delete data;
1082 data = 0;
1083}
1084
1085/*!
1086 \internal
1087 */
1088QThread::QThread(QThreadPrivate &dd, QObject *parent)
1089 : QObject(dd, parent)
1090{
1091 Q_D(QThread);
1092 // fprintf(stderr, "QThreadData %p taken from private data for thread %p\n", d->data, this);
1093 d->data->thread.storeRelaxed(this);
1094}
1095
1096QThreadPrivate::QThreadPrivate(QThreadData *d) : data(d ? d : new QThreadData)
1097{
1098}
1099
1100QThreadPrivate::~QThreadPrivate()
1101{
1102 data->thread.storeRelease(nullptr); // prevent QThreadData from deleting the QThreadPrivate (again).
1103 delete data;
1104}
1105
1106void QThread::setStackSize(uint stackSize)
1107{
1108 Q_UNUSED(stackSize);
1109}
1110
1111uint QThread::stackSize() const
1112{
1113 return 0;
1114}
1115
1116#endif // QT_CONFIG(thread)
1117
1118/*!
1119 \since 5.0
1120
1121 Returns a pointer to the event dispatcher object for the thread. If no event
1122 dispatcher exists for the thread, this function returns \nullptr.
1123*/
1124QAbstractEventDispatcher *QThread::eventDispatcher() const
1125{
1126 Q_D(const QThread);
1127 return d->data->eventDispatcher.loadRelaxed();
1128}
1129
1130/*!
1131 \since 5.0
1132
1133 Sets the event dispatcher for the thread to \a eventDispatcher. This is
1134 only possible as long as there is no event dispatcher installed for the
1135 thread yet.
1136
1137 An event dispatcher is automatically created for the main thread when \l
1138 QCoreApplication is instantiated and on start() for auxiliary threads.
1139
1140 This method takes ownership of the object.
1141*/
1142void QThread::setEventDispatcher(QAbstractEventDispatcher *eventDispatcher)
1143{
1144 Q_D(QThread);
1145 if (d->data->hasEventDispatcher()) {
1146 qWarning(msg: "QThread::setEventDispatcher: An event dispatcher has already been created for this thread");
1147 } else {
1148 eventDispatcher->moveToThread(thread: this);
1149 if (eventDispatcher->thread() == this) // was the move successful?
1150 d->data->eventDispatcher = eventDispatcher;
1151 else
1152 qWarning(msg: "QThread::setEventDispatcher: Could not move event dispatcher to target thread");
1153 }
1154}
1155
1156/*!
1157 \fn bool QThread::wait(unsigned long time)
1158
1159 \overload
1160 \a time is the time to wait in milliseconds.
1161 If \a time is ULONG_MAX, then the wait will never timeout.
1162*/
1163
1164#if QT_CONFIG(thread)
1165
1166/*!
1167 \reimp
1168*/
1169bool QThread::event(QEvent *event)
1170{
1171 if (event->type() == QEvent::Quit) {
1172 quit();
1173 return true;
1174 } else {
1175 return QObject::event(event);
1176 }
1177}
1178
1179/*!
1180 \since 5.2
1181 \threadsafe
1182
1183 Request the interruption of the thread.
1184 That request is advisory and it is up to code running on the thread to decide
1185 if and how it should act upon such request.
1186 This function does not stop any event loop running on the thread and
1187 does not terminate it in any way.
1188
1189 \sa isInterruptionRequested()
1190*/
1191
1192void QThread::requestInterruption()
1193{
1194 Q_D(QThread);
1195 if (d->threadId() == QCoreApplicationPrivate::theMainThreadId.loadAcquire()) {
1196 qWarning(msg: "QThread::requestInterruption has no effect on the main thread");
1197 return;
1198 }
1199 QMutexLocker locker(&d->mutex);
1200 if (!d->running || d->finished || d->isInFinish)
1201 return;
1202 d->interruptionRequested.store(i: true, m: std::memory_order_relaxed);
1203}
1204
1205/*!
1206 \since 5.2
1207
1208 Return true if the task running on this thread should be stopped.
1209 An interruption can be requested by requestInterruption().
1210
1211 This function can be used to make long running tasks cleanly interruptible.
1212 Never checking or acting on the value returned by this function is safe,
1213 however it is advisable do so regularly in long running functions.
1214 Take care not to call it too often, to keep the overhead low.
1215
1216 \code
1217 void long_task() {
1218 forever {
1219 if ( QThread::currentThread()->isInterruptionRequested() ) {
1220 return;
1221 }
1222 }
1223 }
1224 \endcode
1225
1226 \note This can only be called within the thread itself, i.e. when
1227 it is the current thread.
1228
1229 \sa currentThread() requestInterruption()
1230*/
1231bool QThread::isInterruptionRequested() const
1232{
1233 Q_D(const QThread);
1234 // fast path: check that the flag is not set:
1235 if (!d->interruptionRequested.load(m: std::memory_order_relaxed))
1236 return false;
1237 // slow path: if the flag is set, take into account run status:
1238 QMutexLocker locker(&d->mutex);
1239 return d->running && !d->finished && !d->isInFinish;
1240}
1241
1242/*!
1243 \fn template <typename Function, typename... Args> QThread *QThread::create(Function &&f, Args &&... args)
1244 \since 5.10
1245
1246 Creates a new QThread object that will execute the function \a f with the
1247 arguments \a args.
1248
1249 The new thread is not started -- it must be started by an explicit call
1250 to start(). This allows you to connect to its signals, move QObjects
1251 to the thread, choose the new thread's priority and so on. The function
1252 \a f will be called in the new thread.
1253
1254 Returns the newly created QThread instance.
1255
1256 \note the caller acquires ownership of the returned QThread instance.
1257
1258 \warning do not call start() on the returned QThread instance more than once;
1259 doing so will result in undefined behavior.
1260
1261 \sa start()
1262*/
1263
1264class QThreadCreateThread : public QThread
1265{
1266public:
1267 explicit QThreadCreateThread(std::future<void> &&future)
1268 : m_future(std::move(future))
1269 {
1270 }
1271
1272 ~QThreadCreateThread()
1273 {
1274 requestInterruption();
1275 quit();
1276 wait();
1277 }
1278
1279private:
1280 void run() override
1281 {
1282 m_future.get();
1283 }
1284
1285 std::future<void> m_future;
1286};
1287
1288QThread *QThread::createThreadImpl(std::future<void> &&future)
1289{
1290 return new QThreadCreateThread(std::move(future));
1291}
1292
1293/*!
1294 \class QDaemonThread
1295 \since 5.5
1296 \brief The QDaemonThread provides a class to manage threads that outlive QCoreApplication
1297 \internal
1298
1299 Note: don't try to deliver events from the started() signal.
1300*/
1301QDaemonThread::QDaemonThread(QObject *parent)
1302 : QThread(parent)
1303{
1304 // QThread::started() is emitted from the thread we start
1305 connect(sender: this, signal: &QThread::started,
1306 context: this,
1307 slot: [](){ QThreadData::current()->requiresCoreApplication = false; },
1308 type: Qt::DirectConnection);
1309}
1310
1311QDaemonThread::~QDaemonThread()
1312{
1313}
1314
1315#endif // QT_CONFIG(thread)
1316
1317QT_END_NAMESPACE
1318
1319#include "moc_qthread.cpp"
1320

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

source code of qtbase/src/corelib/thread/qthread.cpp