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

Provided by KDAB

Privacy Policy
Learn Advanced QML with KDAB
Find out more

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