Name Description Size Coverage
qatomic.cpp ! \class QAtomicInt \inmodule QtCore \brief The QAtomicInt class provides platform-independent atomic operations on int. \since 4.4 This class is a equivalent to \c{QAtomicInteger<int>}. All other functionality is equivalent. Please see that class for more information. \sa QAtomicInteger, QAtomicPointer 63183 -
qatomic.h 6429 -
qatomic_cxx11.h Attempt to detect whether the atomic operations exist in hardware or whether they are emulated by way of a lock. C++11 29.4 [atomics.lockfree] p1 says The ATOMIC_..._LOCK_FREE macros indicate the lock-free property of the corresponding atomic types, with the signed and unsigned variants grouped together. The properties also apply to the corresponding (partial) specializations of the atomic template. A value of 0 indicates that the types are never lock-free. A value of 1 indicates that the types are sometimes lock-free. A value of 2 indicates that the types are always lock-free. We have a problem when the value is 1: we'd need to check at runtime, but QAtomicInteger requires a constexpr answer (defect introduced in Qt 5.0). So we'll err in the side of caution and say it isn't. 18000 -
qatomicwait.cpp Implementation details: Normally, a call from atomic_notify_one() or atomic_notify_all() corresponds to a call to cond.notify_one() or cond.notify_all(). This simple implementation would require that we keep a distinct wait condition variable per atomic variable, of which there could be an arbitrary number. Instead, we have a limited set of std::condition_variable, which are selected based on the address of the variable being waited/notified on. Because multiple, distinct variables could be sharing the same condition variable, we need to perform a cond.notify_all() call in case the lock is contended by waiters to more than one address, as we can't be sure which one would be woken up by the cond.notify_one() call. We recover some of the performance of notifying a single waker by also storing the address of the variable that was being waited on. If it matches the address of the variable being notified, we can perform a notify_one() call. This also allows us to avoid any system call in case no waiter has yet joined the queue. In case of contention, we store a sentinel address instead, indicating there are waiters to multiple variables. The last waiter to leave a wait queue is responsible for resetting the watched address back to nullptr. Performance details: This implementation is designed for systems where neither the Standard Library's own std::atomic_wait nor operating system futexes are available (read: usually, not the systems Qt is used most frequently on). Therefore, it's designed for simplicity, not performance. Simplifications applied include: - the total number of possible condition variables - the hashing algorithm to select a condition variable (simple XOR) - no attempt to wait for a variable change before calling cond.wait() (no spinning, no HW-assisted wait) Other limitations: We only support 8-, 16-, 32- and 64-bit variables and we require bit-exact comparisons for all bits. This means we do not support objects with padding bits or without unique representations. 6353 -
qatomicwait_p.h being linked into the unit test 2728 -
qbasicatomic.h 12843 -
qexception.cpp ! \class QException \inmodule QtCore \brief The QException class provides a base class for exceptions that can be transferred across threads. \since 5.0 Qt Concurrent supports throwing and catching exceptions across thread boundaries, provided that the exception inherits from QException and implements two helper functions: \snippet code/src_corelib_thread_qexception.cpp 0 QException subclasses must be thrown by value and caught by reference: \snippet code/src_corelib_thread_qexception.cpp 1 If you throw an exception that is not a subclass of QException, the \l{Qt Concurrent} functions will throw a QUnhandledException in the receiver thread. When using QFuture, transferred exceptions will be thrown when calling the following functions: \list \li QFuture::waitForFinished() \li QFuture::result() \li QFuture::resultAt() \li QFuture::results() \endlist 6049 -
qexception.h 2220 -
qfutex_freebsd_p.h 2376 -
qfutex_linux_p.h 2808 -
qfutex_mac_p.h 2413 -
qfutex_p.h 1400 -
qfutex_win_p.h 1611 -
qfuture.h 19403 -
qfuture.qdoc 66182 -
qfuture_impl.h 42591 -
qfutureinterface.cpp 35176 -
qfutureinterface.h 15970 -
qfutureinterface_p.h 6648 -
qfuturesynchronizer.h 1705 -
qfuturesynchronizer.qdoc 3825 -
qfuturewatcher.cpp ! \class QFutureWatcher \reentrant \since 4.4 \inmodule QtCore \ingroup thread \brief The QFutureWatcher class allows monitoring a QFuture using signals and slots. QFutureWatcher is a template class where the template parameter \a T specifies the result type of the QFuture being watched. QFutureWatcher provides information and notifications about a QFuture. Use the setFuture() function to start watching a particular QFuture. The future() function returns the future set with setFuture(). For convenience, several of QFuture's functions are also available in QFutureWatcher: progressValue(), progressMinimum(), progressMaximum(), progressText(), isStarted(), isFinished(), isRunning(), isCanceled(), isSuspending(), isSuspended(), waitForFinished(), result(), and resultAt(). The cancel(), setSuspended(), suspend(), resume(), and toggleSuspended() functions are slots in QFutureWatcher. Status changes are reported via the started(), finished(), canceled(), suspending(), suspended(), resumed(), resultReadyAt(), and resultsReadyAt() signals. Progress information is provided from the progressRangeChanged(), void progressValueChanged(), and progressTextChanged() signals. Throttling control is provided by the setPendingResultsLimit() function. When the number of pending resultReadyAt() or resultsReadyAt() signals exceeds the limit, the computation represented by the future will be throttled automatically. The computation will resume once the number of pending signals drops below the limit. Example: Starting a computation and getting a slot callback when it's finished: \snippet code/src_corelib_thread_qfuturewatcher.cpp 0 Be aware that not all running asynchronous computations can be canceled or suspended. For example, the future returned by QtConcurrent::run() cannot be canceled; but the future returned by QtConcurrent::mappedReduced() can. QFutureWatcher<void> is specialized to not contain any of the result fetching functions. Any QFuture<T> can be watched by a QFutureWatcher<void> as well. This is useful if only status or progress information is needed; not the actual result data. \sa QFuture, {Qt Concurrent} 24133 -
qfuturewatcher.h 4947 -
qfuturewatcher_p.h 1190 -
qgenericatomic.h 965 -
qlatch.cpp ! \class QLatch \internal Implements the same API as \c std::latch (C++20), allowing a single synchronization between threads. \section2 Typical uses \section3 Waiting for threaded work to finish For this use-case, one or more threads perform some work, which needs to finish before the caller thread can proceed. For this, each worker thread calls countDown() once they have finished their work, while the caller thread suspends execution by calling wait(). The operation is best seen in: \code QLatch latch(segments); int y = 0; for (int i = 0; i < segments; ++i) { int yn = (data->height - y) / (segments - i); threadPool->start([&, y, yn]() { convertSegment(y, y + yn); latch.countDown(); }); y += yn; } latch.wait(); \endcode Or, for a single thread: \code QLatch latch(1); QMetaObject::invokeMethod(object, [&]() { doSomething(); latch.countDown(); }, Qt::QueuedConnection); latch.wait(); \endcode In fact, the above is exactly what Qt::BlockingQueued connection does. \section3 Synchronizing execution For this use-case, multiple threads must reach a particular state before any of them may proceed. In this case, all of them call arriveAndWait(), causing all but the last one of them to suspend execution until that last one also arrives. \code QLatch latch(n); for (int i = 0; i < n; ++i) { threadPool->start([] { latch.arriveAndWait(); doStressfulWork(); }); } \endcode \section2 Differences from \c std::latch \list \li Uses \c{int} in the API instead of \c{ptrdiff_t} (note that the max() is the same as libstdc++'s on Linux). \li count_down() is not \c{const} (libstdc++ implementation is). \endlist \omit \section2 Implementation details countDown() must call wakeUp() if the latch counter reaches zero and there are threads waiting to be woken up. Or, conversely, countDown() needs to do nothing after decrementing if the latch counter is still non-zero or there are no waiters. Therefore, we choose the bits so that a non-zero \c{counter} member implies no action required. \endomit 6910 -
qlatch_p.h being linked into the unit test 2339 -
qlocking_p.h 2441 -
qmutex.cpp \class QBasicMutex \inmodule QtCore \brief QMutex POD \internal \ingroup thread - Can be used as global static object. - Always non-recursive - Do not use tryLock with timeout > 0, else you can have a leak (see the ~QMutex destructor) 32000 -
qmutex.h 9393 -
qmutex_p.h Boolean indicating that a timed wait timed out. When it is true, a reference is held. It is there to avoid a race that happens if unlock happens right when the mutex is unlocked. 2609 -
qmutex_unix.cpp 1761 -
qorderedmutexlocker_p.h Locks 2 mutexes in a defined order, avoiding a recursive lock if we're trying to lock the same mutex twice. 3565 -
qpromise.h 3531 -
qpromise.qdoc 10869 -
qreadwritelock.cpp Implementation details of QReadWriteLock: Depending on the valued of d_ptr, the lock is in the following state: - when d_ptr == 0x0: Unlocked (no readers, no writers) and non-recursive. - when d_ptr & 0x1: If the least significant bit is set, we are locked for read. In that case, d_ptr>>4 represents the number of reading threads minus 1. No writers are waiting, and the lock is not recursive. - when d_ptr == 0x2: We are locked for write and nobody is waiting. (no contention) - In any other case, d_ptr points to an actual QReadWriteLockPrivate. 23559 -
qreadwritelock.h 11501 -
qreadwritelock_p.h ! \internal Describes the state of the QReadWriteLock whose private is \a dd. Returns one of: \list \li 0 (unlocked) \li \c IsRecursiveLock (still unlocked) \li \c StateLockedForRead \li \c{StateLockedForRead | IsRecursiveLock} \li \c StateLockedForWrite \li \c{StateLockedForWrite | IsRecursiveLock} \li \c{StateLockedForWrite | IsRecursiveLock | MultiplyLocked} = \c RecursivelyLockedForWrite \endlist 5083 -
qresultstore.cpp ! \internal Finds result in \a store by \a index 6609 -
qresultstore.h ResultStore stores indexed results. Results can be added and retrieved either individually batched in a QList. Retriveing results and checking which indexes are in the store can be done either by iterating or by random access. In addition results can be removed from the front of the store, either individually or in batches. 7692 -
qrunnable.cpp ! \internal Prints a warning and returns nullptr. 3287 -
qrunnable.h 4197 -
qsemaphore.cpp ! \class QSemaphore \inmodule QtCore \brief The QSemaphore class provides a general counting semaphore. \threadsafe \ingroup thread A semaphore is a generalization of a mutex. While a mutex can only be locked once, it's possible to acquire a semaphore multiple times. Semaphores are typically used to protect a certain number of identical resources. Semaphores support two fundamental operations, acquire() and release(): \list \li acquire(\e{n}) tries to acquire \e n resources. If there aren't that many resources available, the call will block until this is the case. \li release(\e{n}) releases \e n resources. \endlist There's also a tryAcquire() function that returns immediately if it cannot acquire the resources, and an available() function that returns the number of available resources at any time. Example: \snippet code/src_corelib_thread_qsemaphore.cpp 0 A typical application of semaphores is for controlling access to a circular buffer shared by a producer thread and a consumer thread. The \l{Producer and Consumer using Semaphores} example shows how to use QSemaphore to solve that problem. A non-computing example of a semaphore would be dining at a restaurant. A semaphore is initialized with the number of chairs in the restaurant. As people arrive, they want a seat. As seats are filled, available() is decremented. As people leave, the available() is incremented, allowing more people to enter. If a party of 10 people want to be seated, but there are only 9 seats, those 10 people will wait, but a party of 4 people would be seated (taking the available seats to 5, making the party of 10 people wait longer). \sa QSemaphoreReleaser, QMutex, QWaitCondition, QThread, {Producer and Consumer using Semaphores} 22595 -
qsemaphore.h 2787 -
qthread.cpp QPostEventList 43624 -
qthread.h On architectures and platforms we know, interpret the thread control block (TCB) as a unique identifier for a thread within a process. Otherwise, fall back to a slower but safe implementation. As per the documentation of currentThreadId, we return an opaque handle as a thread identifier, and application code is not supposed to use that value for anything. In Qt we use the handle to check if threads are identical, for which the TCB is sufficient. So we use the fastest possible way, rather than spend time on returning some pseudo-interoperable value. 6374 -
qthread_p.h BindingStatusOrList is basically a QBiPointer (as found in declarative) with some helper methods to manipulate the list. BindingStatusOrList starts its life in a null state and supports the following transitions 0 state (initial) / \ / \ v v pending object list----------->binding status Note that binding status is the final state, and we never transition away from it 11823 -
qthread_unix.cpp 38353 -
qthread_win.cpp QThreadData 17218 -
qthreadpool.cpp QThread wrapper, provides synchronization against a ThreadPool 27145 -
qthreadpool.h 3559 -
qthreadpool_p.h 4333 -
qthreadstorage.cpp the destructors vector has already been destroyed, yet a new QThreadStorage is being allocated. this can only happen during global destruction, at which point we assume that there is only one thread. in order to keep QThreadStorage working, we need somewhere to store the data, best place we have in this situation is at the tail of the current thread's tls vector. the destructor is ignored, since we have no where to store it, and no way to actually call it. 10323 -
qthreadstorage.h 4670 -
qthreadstorage_p.h 760 -
qtsan_impl.h 2642 -
qwaitcondition.h 1724 -
qwaitcondition.qdoc 6265 -
qwaitcondition_p.h QWAITCONDITION_P_H 1296 -
qwaitcondition_unix.cpp 5283 -
qwaitcondition_win.cpp 5210 -
qyieldcpu.h 1902 -
qyieldcpu.qdoc 2169 -