summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread
Commit message (Collapse)AuthorAgeFilesLines
* Mark ResultStoreBase as finalSona Kurazyan2022-01-241-1/+1
| | | | | | | | | | | | | The class is not intended for inheriting from it (see also e5029063057c38297f188ccfefef7b1bcd781a76), so we can mark it as final to explicitly forbid this. The tests were still using it as a base class to clean the results during destruction, so fix them accordingly. Task-number: QTBUG-99883 Pick-to: 6.3 Change-Id: I4a7ee3e2b462bd704e4b5a95ed733144805d6e5b Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* QFuture: add a missing include for qpromise.hSona Kurazyan2022-01-242-5/+9
| | | | | | | | | | | | | QPromise is now used in qfuture_impl.h, so we need to include it. Remove qfuture.h include from qpromise.h, to avoid circular dependency. As a drive-by, simplify a type-trait: is_convertible_v<T, S> is true whenever is_same_v<T, S> is, so we don't need to instantiate both. Fixes: QTBUG-100144 Pick-to: 6.3 6.2 Change-Id: Ic6df43d96d9d168cc44c2949e41c5e490f4c50ce Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Add a note for making ResultStoreBase's internal members privateSona Kurazyan2022-01-211-1/+2
| | | | | | | | | | | There's no class inheriting from ResultStoreBase (and likely won't be), so the destructor was marked to be made non-virtual in Qt 7. For the same reason, the internal members don't need to be protected, and the class shouldn't have "Base" in its name. Add a note about it. Task-number: QTBUG-99883 Change-Id: I00d7a96d99d2c326d29bd421235a15d68b4d4e5c Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Optimize ContinuationWrapper used for support of move-only continuationsSona Kurazyan2022-01-212-4/+12
| | | | | | | | | | | | | | | After QFuture continuations became non-copyable (see earlier commits), we have to always use ContinuationWrapper to save the continuations inside std::function, since it requires the callable to be copyable. Optimize the wrapper, by storing the callable directly (instead of using a ref-counted QSharedPointer) and introducing a fake copy-constructor that makes sure that it's never called. Pick-to: 6.3 6.2 Change-Id: I0ed5f90ad62ede3b5c6d6e56ef58eb6377122920 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Create QFutures returned by QtFuture::when* methods via QPromiseSona Kurazyan2022-01-211-10/+10
| | | | | | | | | | | | | | This is required to ensure that the continuation attached to a QFuture returned by QtFuture::when* methods is cleaned in the destructor of the associated QPromise, so that it doesn't keep any ref-counted copies to the shared data, thus preventing it from being deleted. Task-number: QTBUG-99534 Pick-to: 6.3 Change-Id: If4e2929b2e638d6b48c95f0aef9dc886066cedbe Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Use QPromise when creating continuations to avoid memory leaksSona Kurazyan2022-01-211-136/+102
| | | | | | | | | | | | | | | | | Continuations were using QFutureInterface to create and return the associated future to the user. Attaching a continuation to the returned future could cause memory leaks (described in an earlier commit). Use a QPromise when saving the continuation, to make sure that the attached continuation is cleaned in the destructor of the associated QPromise, so that it doesn't keep any ref-counted copies to the shared data, thus preventing it from being deleted. Task-number: QTBUG-99534 Pick-to: 6.3 6.2 Change-Id: I52d5501292095d41d1e060b7dd140c8e5d01335c Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Fix memory leaks when capturing a QFuture in its continuationSona Kurazyan2022-01-213-3/+24
| | | | | | | | | | | | | | | | | | | | | | Capturing a QFuture in the continuations attached to it results in memory leaks. QFuture's ref-counted data can only be deleted when the last copy referencing the data gets deleted. The saved continuation that keeps a copy of the future (as in case of the lambda capture) will prevent the data from being deleted. So we need to manually clean the continuation after it is run. But this doesn't solve the problem if the continuation isn't run. In that case, clean the continuation in the destructor of the associated QPromise. To avoid similar leaks, internally we should always create futures via QPromise, instead of the ref-counted QFutureInterface, so that the continuation is always cleaned in the destructor. Currently QFuture continuations and QtFuture::when* methods use QFutureInterface directly, which will be fixed by the follow-up commits. Fixes: QTBUG-99534 Pick-to: 6.3 6.2 Change-Id: Ic13e7dffd8cb25bd6b87e5416fe4d1a97af74c9b Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Work-around crash in QThreadPool QThread usageAllan Sandfeld Jensen2022-01-212-2/+6
| | | | | | | | | | | This works around mismatch in threads starting and restarting QThreads, and is safe since we don't need to establish a binding, and objectName access in QThreadPool is locked behind a mutex. Pick-to: 6.3 6.2 Fixes: QTBUG-96718 Change-Id: Id3f75e4f8344796ca658899645219fe3373ddd6d Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* QtCore: replace qSwap with std::swap/member-swap where possibleMarc Mutz2022-01-203-4/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | qSwap() is a monster that looks for ADL overloads of swap() and also detects the noexcept of the wrapped swap() function, so it should only be used when the argument type is unknown. In the vast majority of cases, the type is known to be efficiently std::swap()able or to have a member-swap. Call either of these. For the common case of pointer types, circumvent the expensive trait checks on std::swap() by providing a hand-rolled qt_ptr_swap() template, the advantage being that it can be unconditionally noexcept, removing all type traits instantiations. Don't document it, otherwise we'd be unable to pick it to 6.2. Effects on Clang -ftime-trace of a PCH'ed libQt6Gui.so build: before: **** Template sets that took longest to instantiate: [...] 27766 ms: qSwap<$> (9073 times, avg 3 ms) [...] 2806 ms: std::swap<$> (1229 times, avg 2 ms) (30572ms) after: **** Template sets that took longest to instantiate: [...] 5047 ms: qSwap<$> (641 times, avg 7 ms) [...] 3371 ms: std::swap<$> (1376 times, avg 2 ms) [qt_ptr_swap<$> does not appear in the top 400, so < 905ms] (< 9323ms) As a drive-by, remove superfluous inline keywords and template ornaments. Task-number: QTBUG-97601 Pick-to: 6.3 6.2 Change-Id: I88f9b4e3cbece268c4a1238b6d50e5712a1bab5a Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Joerg Bornemann <joerg.bornemann@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Read QThreadPool::objectName thread-safeAllan Sandfeld Jensen2022-01-132-6/+10
| | | | | | | | | | QThreadPool allows method calls from any thread, but QObject does not so copy objectName so we may use it locally under our own lock. Pick-to: 6.3 6.2 Task-number: QTBUG-99775 Change-Id: Ib28910649f5d0f9ce698c7da495069635d608d03 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Don't access QObject::objectName during QThread startVolker Hilsheimer2022-01-123-6/+16
| | | | | | | | | | | | | This is a data race, as the thread accesses QObject::objectName on the QThread instance while the thread owning the QThread might modify the objectName. Instead, make a copy in the QThreadPrivate that can be accessed safely. Task-number: QTBUG-96718 Pick-to: 6.3 6.2 5.15 Change-Id: I10701551d498993ca5055daf161636bfb648840c Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* QFutureCallOutInterface: de-inline dtorMarc Mutz2022-01-052-1/+3
| | | | | | | Pick-to: 6.3 Task-number: QTBUG-45582 Change-Id: I5f3411e1dcea4b76fb0e729f612516db3163c93a Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QThread: fix UB (invalid enum value) on Private::PriorityMarc Mutz2022-01-033-6/+6
| | | | | | | | | | | | | | | | | | | | | The Unix code stores an additional flag, ThreadPriorityResetFlag, in the Policy enum, but ubsan does not approve: qthread_unix.cpp:303:30: runtime error: load of value 2147483648, which is not a valid value for type 'Priority' qthread_unix.cpp:304:75: runtime error: load of value 2147483648, which is not a valid value for type 'Priority' Fix by making the variable of std::underlying_type_t<Priority>. The masking and unmasking code can now be simplified, too. In the Windows version, replace some switch targets with equivalent ones to keep -Wswitch-like warnings, though I hasten to note that both switches use a default case, so have anyway implicitly disabled said warning. Pick-to: 6.3 6.2 5.15 Change-Id: Ie4ea7d05e2928d2755ad12d36535197f85493191 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* QThread/Unix: extract duplicate codeMarc Mutz2021-12-301-36/+27
| | | | | | | | | | | | | | Extract function terminate_on_exception() that de-duplicates the #ifdef'ery around the try/catch and the handling of the pthread cancellation pseudo-exception. Apart from de-duplicating complex code, it will also help suppressing a ubsan false positive, which is why we're picking it all the way to 5.15. Pick-to: 6.3 6.2 5.15 Change-Id: I99ad2c0618b8dc30801931df09400c6611d9f9e4 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Eradicate Q_FOREVER from header filesMarc Mutz2021-12-281-5/+5
| | | | | | | | | The qgenericatomic.h occurrences are getting in the way of splitting up qglobal.h, so inline the define. Task-number: QTBUG-99313 Change-Id: I0d6e3553c5ed4ac9e426bef2fe07d2672d73c671 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QThread::idealThreadCount: use the thread affinity setThiago Macieira2021-12-162-7/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Instead of returning the total number of logical processors in the system, which we may not be allowed to wholly run on, use the affinity set that the calling thread is allowed to use. Implemented for Linux and FreeBSD only, with up to 4x the number of processors than CPU_SETSIZE has as default (that would be 4096 logical processors on Linux, 1024 on FreeBSD). Implementation for Windows is possible, but the API there is always limited to 64, so I'm unsure if it is correct. Darwin (macOS) does not have this capability. Testing: $ ./tst_qthread idealThreadCount | grep QDEBUG QDEBUG : tst_QThread::idealThreadCount() Ideal thread count: 8 $ taskset 3 ./tst_qthread idealThreadCount | grep QDEBUG QDEBUG : tst_QThread::idealThreadCount() Ideal thread count: 2 [ChangeLog][QtCore][QThread] idealThreadCount() will now return the number of logical processors that the current process (thread) has assigned in its affinity set, instead of the total number of processors in the system. These two numbers can be different if the process is launched by the parent with a different affinity set, with tools like Linux's taskset(1) or schedtool(1). This is currently implemented for Linux and FreeBSD. Change-Id: I2cffe62afda945079b63fffd16bd086f64f5f314 Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QtFuture::connect: exclude QPrivateSignal from the resulting future typeSona Kurazyan2021-12-111-7/+45
| | | | | | | | | | | | Filter out the last argument of type QPrivateSignal from the signal's arguments passed to QtFuture::connect(). Pick-to: 6.2 Fixes: QTBUG-92501 Change-Id: Idcd6baba1f01fcc94fa64b1c7030a629d01ed7a1 Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Enable other integer sizes in the bootstrap library's QAtomicIntegerThiago Macieira2021-12-111-0/+8
| | | | | | | | | They're not atomic anyway. But it does make it possible to use QAtomicInteger in both bootstrapped and non-bootstrapped code. Change-Id: I2cffe62afda945079b63fffd16bcc67e082d92ae Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* QThread::create(): request interruption and join on destructionGiuseppe D'Angelo2021-12-071-0/+16
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | If one destroys a running QThread, so far the behavior has been to crash (à la std::thread) -- assuming the thread hasn't already signalled that it has finished. This behavior is hostile to solutions such as using QThread::create(), which always require a wait() before destroying the thread object. We can use the opportunity to change the behavior without breaking any valid code. Instead of crashing, inside QThread's destructor we can ask the new thread to quit, and then join it (à la std::jthread). This simplifies the implementation of long-living runnables and the code that manages them. Deploying this solution for the whole QThread class may not be entirely painless. While no correct code would work differently with the proposed changes, incorrect code that deletes a running thread would no longer crash "loudly" -- instead, it might deadlock "quietly", have memory corruptions, etc. Hence I'm limiting this approach to only the threads created by QThread::create(), at least for the time being. This also side-steps perhaps the biggest problem of generalizing the approach, which is that placing such interrupt+join logic into~QThread's destructor would cause it to be run _after_ a QThread subclass' own destructor has run, destroying the subclass' data members too early. This might create an antipattern if one chooses to subclass QThread. With create(), a subclass in question exists, and it indeed has NSDMs, but it's entirely under our control (in fact, I'm placing the logic just in its dtor). [ChangeLog][QtCore][QThread] Destroying a QThread object created by QThread::create() while the thread that it manages is still running will now automatically ask that thread to quit, and will wait until the thread has finished. Before, this resulted in a program crash. See the documentation of QThread::~QThread() for more details. Change-Id: Ib268b13da422e277ee3ed6f6c7b2ecc8cea5750c Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Fix QFuture continuations/handlers to work with move-only callablesSona Kurazyan2021-12-011-8/+43
| | | | | | | | | | | | | | | | std::function, which is used to store the type-erased continuation lambdas, requires the passed callable to be copy-constructible. This makes impossible to use move-only callables with continuations/handlers. In particular, it makes impossible passing lambdas that are capturing move-only objects. The workaround is to store the continuation lambda inside a wrapper for the callable, which stores the move-only lambda in a QSharedPtr and can be stored in std::function, since it's copyable. Pick-to: 6.2 Fixes: QTBUG-98493 Change-Id: I8b7a22fcf68dc132b3c533216a7a1665e9f9fb0a Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* QThread::wait: Clarify documentation for unsigned long overloadFabian Kosmale2021-11-271-0/+3
| | | | | | | | | | It is not immediately clear from the signature that the time parameter's unit is miliseconds. Pick-to: 6.2 Change-Id: Ifee3c6410b6b2352e75571cc53578a660aabb32d Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Mention QtFuture::when* functions in QFuture's docsSona Kurazyan2021-11-261-4/+7
| | | | | | | | | Also fix an unrelated minor issue in QtFuture::whenAll docs. Task-number: QTBUG-86714 Change-Id: I45f06b17db0508be10215e6d260ef76ede3077fb Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Add support for combining multiple QFuturesSona Kurazyan2021-11-203-0/+421
| | | | | | | | | | | [ChangeLog][QtCore] Added QtFuture::whenAll() and QtFuture::whenAny() functions, returning a QFuture that becomes ready when all or any of the supplied futures complete. Task-number: QTBUG-86714 Change-Id: I2bb7dbb4cdc4f79a7a4fd494142df6a0f93a2b39 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Re-apply "QReadWriteLock: replace (QWaitCondition, QMutex) with ↵Marc Mutz2021-11-202-22/+25
| | | | | | | | | | | | | | std::(condition_variable, mutex)" This reverts commit 1283ee324578e4cf5cc210d8d3c89647d6c56ec3. We now have wrappers around std::mutex and std::condition_variable that fall back to QMutex and QWaitCondition on the broken Integrity toolchain. Use them. Change-Id: I881aa931167b845b489713048b57ccc5f79d4237 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* QReadWriteLock: replace a QHash with a QVarLengthArray<., 16>Marc Mutz2021-11-162-7/+24
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The QHash was used to track the recursion level of concurrent readers. But it makes no sense to optimize this data structure for O(1) lookup speed, since once you go beyond a few threads, a mutex-based solution falls apart, anyway. So use an unordered QVarLengthArray with preallocated capacity 16 instead. Lookup and erasure are now O(N), but tracking the first 16 threads that concurrently lock this shared mutex for reading no longer allocates memory (except for the Private class that contains the data structure). Results on my machine (recursive only): thread count: 16 ********* Start testing of tst_QReadWriteLock ********* Config: Using QtTest library 6.3.0, Qt 6.3.0 (x86_64-little_endian-lp64 shared (dynamic) release build; by GCC 11.2.1 20211101), ubuntu 20.04 [...] PASS : tst_QReadWriteLock::uncontended(QReadWriteLock, read, recursive: 1) RESULT : tst_QReadWriteLock::uncontended():"QReadWriteLock, read, recursive: 1": - 51 msecs per iteration (total: 51, iterations: 1) + 38 msecs per iteration (total: 77, iterations: 2) PASS : tst_QReadWriteLock::uncontended(QReadWriteLock, write, recursive: 1) RESULT : tst_QReadWriteLock::uncontended():"QReadWriteLock, write, recursive: 1": - 31 msecs per iteration (total: 62, iterations: 2) + 29 msecs per iteration (total: 58, iterations: 2) PASS : tst_QReadWriteLock::uncontended(QReadWriteLock, read, recursive: 2) RESULT : tst_QReadWriteLock::uncontended():"QReadWriteLock, read, recursive: 2": - 89 msecs per iteration (total: 89, iterations: 1) + 75 msecs per iteration (total: 75, iterations: 1) PASS : tst_QReadWriteLock::uncontended(QReadWriteLock, write, recursive: 2) RESULT : tst_QReadWriteLock::uncontended():"QReadWriteLock, write, recursive: 2": - 62 msecs per iteration (total: 62, iterations: 1) + 56 msecs per iteration (total: 56, iterations: 1) PASS : tst_QReadWriteLock::uncontended(QReadWriteLock, read, recursive: 32) RESULT : tst_QReadWriteLock::uncontended():"QReadWriteLock, read, recursive: 32": - 1,357 msecs per iteration (total: 1,357, iterations: 1) + 1,154 msecs per iteration (total: 1,154, iterations: 1) PASS : tst_QReadWriteLock::uncontended(QReadWriteLock, write, recursive: 32) RESULT : tst_QReadWriteLock::uncontended():"QReadWriteLock, write, recursive: 32": - 1,067 msecs per iteration (total: 1,067, iterations: 1) + 984 msecs per iteration (total: 984, iterations: 1) [...] PASS : tst_QReadWriteLock::readOnly(QReadWriteLock, recursive: 1) RESULT : tst_QReadWriteLock::readOnly():"QReadWriteLock, recursive: 1": - 11,561 msecs per iteration (total: 11,561, iterations: 1) + 6,704 msecs per iteration (total: 6,704, iterations: 1) PASS : tst_QReadWriteLock::readOnly(QReadWriteLock, recursive: 2) RESULT : tst_QReadWriteLock::readOnly():"QReadWriteLock, recursive: 2": - 16,173 msecs per iteration (total: 16,173, iterations: 1) + 13,053 msecs per iteration (total: 13,053, iterations: 1) PASS : tst_QReadWriteLock::readOnly(QReadWriteLock, recursive: 32) RESULT : tst_QReadWriteLock::readOnly():"QReadWriteLock, recursive: 32": - 178,597 msecs per iteration (total: 178,597, iterations: 1) + 146,008 msecs per iteration (total: 146,008, iterations: 1) [...] PASS : tst_QReadWriteLock::writeOnly(QReadWriteLock, recursive: 1) RESULT : tst_QReadWriteLock::writeOnly():"QReadWriteLock, recursive: 1": - 65,165 msecs per iteration (total: 65,165, iterations: 1) + 64,503 msecs per iteration (total: 64,503, iterations: 1) PASS : tst_QReadWriteLock::writeOnly(QReadWriteLock, recursive: 2) RESULT : tst_QReadWriteLock::writeOnly():"QReadWriteLock, recursive: 2": - 70,665 msecs per iteration (total: 70,665, iterations: 1) + 69,812 msecs per iteration (total: 69,812, iterations: 1) PASS : tst_QReadWriteLock::writeOnly(QReadWriteLock, recursive: 32) RESULT : tst_QReadWriteLock::writeOnly():"QReadWriteLock, recursive: 32": - 50,811 msecs per iteration (total: 50,811, iterations: 1) + 57,659 msecs per iteration (total: 57,659, iterations: 1) Recursive mode is really, really expensive, even with this patch applied. Change-Id: I36a164cf09462b69dce7e553f96afcebb49e3dbf Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QFuture: extend the docs to explain how to cancel continuation chainSona Kurazyan2021-11-151-0/+24
| | | | | | | Task-number: QTBUG-97582 Change-Id: Ib31d0dfb7a74bb88802a21c5875edd789e412529 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Update documentation of QFuture continuationsSona Kurazyan2021-11-151-19/+44
| | | | | | | | | | | | Mention that the futures returned by continuations will stay uninitialized, until the corresponding continuation/handler starts executing and do some general improvments to make the docs more readable. Task-number: QTBUG-97582 Pick-to: 6.2 Change-Id: I141ff1630b22ec7a856a457a41a69efec980d44b Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* QFuture: support cancellation of continuation chain through parentSona Kurazyan2021-11-134-4/+37
| | | | | | | | | | | | | | | | | | | This change allows canceling the chain of continuations attached to a future through canceling the future itself at any point of execution of the chain. [ChangeLog][QtCore][Important Behavior Changes] The chain of continuations attached to a future now can be cancelled through cancelling the future itself at any point of the execution of the chain, as it was documented. Previously canceling the future would cancel the chain only if it was done before the chain starts executing, otherwise the cancellation would be ignored. Now the part of the chain that wasn't started at the moment of cancellation will be canceled. Task-number: QTBUG-97582 Change-Id: I4c3b3c68e34d3a044243ac9a7a9ed3c38b7cb02e Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Add missing qt namespace in qthreadstorage.hAlexey Edelev2021-11-111-0/+4
| | | | | | | | | | | Wrap 'else QT_CONFIG(thread)' block in qthreadstorage.h with qt namespace Pick-to: 6.2 Fixes: QTBUG-98085 Change-Id: Ica1817fa6beeaf9e4883edaa8738f042b29f0c5e Reviewed-by: Kirill Burtsev <kirill.burtsev@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Doc: Fix qdoc warningsVenugopal Shivashankar2021-10-231-3/+8
| | | | | | | | | | | | | | | | | src/corelib/kernel/qmetatype.cpp:1605: (qdoc) warning: Command '\snippet (//! [[implicit]])' failed at end of file 'qmetatyp> src/corelib/kernel/qmetatype.cpp:1615: (qdoc) warning: Command '\snippet (//! [[member]])' failed at end of file 'qmetatype/> src/corelib/kernel/qmetatype.cpp:1626: (qdoc) warning: Command '\snippet (//! [[memberOk]])' failed at end of file 'qmetatyp> src/corelib/kernel/qmetatype.cpp:1639: (qdoc) warning: Command '\snippet (//! [[unaryfunc]])' failed at end of file 'qmetaty> src/corelib/text/qbytearraymatcher.cpp:233: (qdoc) warning: No such parameter 'view' in QByteArrayMatcher::indexIn() src/corelib/time/qdatetime.cpp:1854: (qdoc) warning: Can't link to 'QLocaleie:pmText()' src/corelib/thread/qsemaphore.cpp:494: (qdoc) warning: Undocumented return value (hint: use 'return' or 'returns' in the text src/corelib/thread/qsemaphore.cpp:505: (qdoc) warning: Undocumented parameter 'timeout' in QSemaphore::try_acquire_for() src/corelib/thread/qsemaphore.cpp:505: (qdoc) warning: Undocumented return value (hint: use 'return' or 'returns' in the text src/corelib/thread/qsemaphore.cpp:516: (qdoc) warning: Undocumented parameter 'tp' in QSemaphore::try_acquire_until() src/corelib/thread/qsemaphore.cpp:516: (qdoc) warning: Undocumented return value (hint: use 'return' or 'returns' in the text Change-Id: Ib612c69525ec7542f2ad3dd9a07e89f266718fd8 Reviewed-by: Topi Reiniö <topi.reinio@qt.io>
* corelib: Fix typos in documentationJonas Kvinge2021-10-126-9/+9
| | | | | | Pick-to: 5.15 6.2 Change-Id: I64d63af708bc6ddaabd12450eb3089e5077f849e Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* corelib: Fix typos in source code commentsJonas Kvinge2021-10-124-5/+5
| | | | | | Pick-to: 6.2 Change-Id: Ic78afb67143112468c6f84677ac88f27a74b53aa Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* avoid max macro expansion on windows if NOMINMAX is missingAlexander Neumann2021-10-111-1/+1
| | | | | | Pick-to: 6.2 Change-Id: I1c19da59bdf97a434be52239c2a5b1b517341bcb Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Optimize QPromise destructorSona Kurazyan2021-10-083-8/+33
| | | | | | | | | Unify cancel and finish in QPromise destructor in a single call. This saves us one extra mutex lock and atomic state change. Task-number: QTBUG-84977 Change-Id: Iac06302c39a2863008b27325fcf6792d4f58c8ae Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* QtTest: fix build with MinGW/GCC 9: no std::mutex supportThiago Macieira2021-10-081-9/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Unfortunately we can't depend on the C++11, 14 or 17 Standard Library, which is not properly and completely implemented everywhere. All Library features above C++98 must be checked with their corresponding __cpp_lib macro before use. This does not apply to the C++17 Core Language. qwaitcondition_p.h:144:20: error: 'mutex' in namespace 'std' does not name a type 144 | using mutex = std::mutex; | ^~~~~ qwaitcondition_p.h:59:1: note: 'std::mutex' is defined in header '<mutex>'; did you forget to '#include <mutex>'? 58 | #include <condition_variable> +++ |+#include <mutex> 59 | #include <mutex> qwaitcondition_p.h:145:33: error: 'condition_variable' in namespace 'std' does not name a type 145 | using condition_variable = std::condition_variable; | ^~~~~~~~~~~~~~~~~~ qwaitcondition_p.h:59:1: note: 'std::condition_variable' is defined in header '<condition_variable>'; did you forget to '#include <condition_variable>'? 58 | #include <condition_variable> +++ |+#include <condition_variable> 59 | #include <mutex> Pick-to: 6.2 Change-Id: I2bbf422288924c198645fffd16a9249e5330136a Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Add a safer way to use QThreadPool::reserveThreadAllan Sandfeld Jensen2021-10-062-0/+54
| | | | | | | | | Add startOnReservedThread that specifically releases a reserved thread and uses it atomically for a given task. This can make a positive number of reserved threads work. Change-Id: I4bd1dced24bb46fcb365f12cbc9c7905dc66cdf1 Reviewed-by: David Faure <david.faure@kdab.com>
* Remove checks for features available in C++17Ievgenii Meshcheriakov2021-10-021-4/+0
| | | | | | | | | | This patch removes most of the checks that are made using C++20 __cpp_* macros for features available in C++17 and earlier. Library feature check macros (__cpp_lib_*) are unaffected. Change-Id: I557b2bd0d4ff09b13837555e9880eb28e0355f64 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Cleanup of qthreadpoolAllan Sandfeld Jensen2021-10-012-40/+54
| | | | | | | | | | | | | Don't bother overwaiting in waitForDone(), if it was done at one point after it was called we can return true. And do not stop threads recently awakened by a startThread call as they have tasks to do. Make allowing at least one thread regardless of reservation more standard instead of hacked in certain places. Pick-to: 6.2 Change-Id: I304bcdc5822f440d5e72fc33ba2aa1678c9ba0d0 Reviewed-by: David Faure <david.faure@kdab.com>
* QThread: Reset the system thread ID when thread exits on UnixIevgenii Meshcheriakov2021-09-291-0/+4
| | | | | | | | | | | | | | | | | | | | | Unix QThread implementation stores pthread_t as a system thread ID when the thread is created, but never resets the system ID when those threads are destroyed. Some implementations may reuse the same thread IDs for new threads, and this may cause QThread::wait() to erroneously complain that "Thread tried to wait on itself". This patch sets the system thread ID to nullptr when the thread is about to exit and be destroyed by the system. A regression test is added to tst_qthread. Fixes: QTBUG-96846 Pick-to: 5.15 6.2 Change-Id: I0850425dd0e09af50e59c9038e7e662a2a624beb Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QThread: Remove superfluous initialization of threadId on UnixIevgenii Meshcheriakov2021-09-281-1/+3
| | | | | | | | | | | | | | The thread ID is already initialized inside QThread::start() while the thread lock is taken. This is completed before the attempted initialization in QThreadPrivate::start() because it tries to take the same lock. Task-number: QTBUG-96846 Pick-to: 5.15 6.2 Change-Id: Ic9588f3e2e2f3c2180afbed8ec01155b33043eb3 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QThreadPrivate: Remove threadForIdFabian Kosmale2021-09-221-3/+0
| | | | | | | | | The thread build variant is not implemented; the no-thread one simply returns the current thread. As this has no utility at best and misleading at worst, remove those functions. Change-Id: I93ee45ae7d55e3a7ad1f03168b14149a5d4c9253 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Plaster [[nodiscard]] on some RAII classesGiuseppe D'Angelo2021-09-191-2/+2
| | | | | | | | | | | | | | | | | | | | | | | The idea is to prevent silly mistakes such as QMutexLocker(mutex); doSomething(); where the locker is constructed and destroyed immediately. Compilers don't normally warn in these cases (as the constructor/destructor pairs involved do have side effects), but we can mark the type as [[nodiscard]] to encourage warnings. There is another couple of classes for which this would make sense (notably, the R/W lockers), but unfortunately those are exported classes, and GCC has a bug where one can't mix two different attribute syntaxes on the same entity [1], so I'm skipping those. [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102399 Change-Id: I75a2443dc71e6b80613b8edd52a04d3379355728 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QThreadPool: Fix restarting of expired threadsIevgenii Meshcheriakov2021-09-151-0/+5
| | | | | | | | | | | | | | | | Ensure that expired threads have actually finished before attempting to restart them. Calling start() on a thread that is not yet finished does nothing. Add a regression test into tst_qthreadpool that attempts to trigger reuse of expired threads and verifies that all submitted tasks execute. Fixes: QTBUG-72872 Pick-to: 6.2 Change-Id: I2109b628b8a4e91491115dc56aebf3eb249646b5 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Doc: fix qdoc warning from wrong function prototypesVolker Hilsheimer2021-09-061-4/+4
| | | | | | | | | | | | std::chrono values are passed by const reference. Still warnings from undocumented parameters, but rephrasing the documentation doesn't make it better in this case, so perhaps qdoc needs a way to suppress the warning. Adding an \omit block where the parameters or return values are mentioned doesn't help. Change-Id: I7d495d73d8367d9d90dd33a4880ac7c978382d19 Reviewed-by: Paul Wicking <paul.wicking@qt.io>
* Fix build on riscv32Fabrice Fontaine2021-09-021-0/+5
| | | | | | | | | | | | | | | | | | riscv32 fails to build because __NR_futex is not defined on this architecture: In file included from thread/qmutex_linux.cpp:45, from thread/qmutex.cpp:804: thread/qfutex_p.h: In function 'int QtLinuxFutex::_q_futex(int*, int, int, quintptr, int*, int)': thread/qfutex_p.h:116:30: error: '__NR_futex' was not declared in this scope; did you mean '_q_futex'? 116 | int result = syscall(__NR_futex, addr, op | FUTEX_PRIVATE_FLAG, val, val2, addr2, val3); | ^~~~~~~~~~ | _q_futex Pick-to: 6.1 6.2 Fixes: QTBUG-96067 Change-Id: Ib6a9bcc496f37e69ac39362cb0a021fccaf311f5 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* wasm: enable the new event dispatcher for qtcoreMorten Johan Sørvig2021-08-271-0/+4
| | | | | | | | | Use the new event dispatcher for all non-GUI threads, nn practice for the main thread when using QCoreApplication, and when calling QThread::exec(). Change-Id: I9184d52532e06da7e6a87ee27c7d53e0d15e693a Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
* Improve docs for QFuture continuationsSona Kurazyan2021-08-101-43/+47
| | | | | | | | | | | Replace phrases like "future has been running", "parent" with more precise descriptions. Pick-to: 6.1 6.2 Fixes: QTBUG-95273 Change-Id: Ibd5a464007d41cc437da49ba250b9ea0a46078c6 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* QProperty: Only try to avoid TLS access if currentThreadId is fasterFabian Kosmale2021-08-041-0/+3
| | | | | | | | | | | We will not gain anything if we have to do multiple function calls to obtain the thread id. Therefore we introduce a macro to signal that we have a fast implementation of currentThreadId, and only use the function if it is defined. Pick-to: 6.2 Change-Id: I3347489ea91992896bb753b796ae26e391c2c99c Reviewed-by: Lars Knoll <lars.knoll@qt.io>
* Don't report results when the results list is emptySona Kurazyan2021-07-272-0/+8
| | | | | | | | | | | | | | | | | | When inserting items into the result store, a ResultItem is created, which stores a pointer to the results list and their size. If the size of the ResultItem is set to 0, it means that a single result is stored. In case of trying to report results via an empty list, the size is 0, so result store treats it as a single result. Added checks before storing the results to make sure that the result list isn't empty. Note that empty lists are allowed in some cases for the filter mode, because ResultStoreBase::addResults() knows how to handle those cases correctly. Task-number: QTBUG-80957 Pick-to: 5.15 6.1 6.2 Change-Id: I399af4c3eef6adf82fea5df031fe9a9075006b1f Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Doc: Ensure deprecated APIs in Qt Core are documented as suchNico Vertriest2021-07-232-23/+15
| | | | | | | | | | Added \deprecated [version_since] when needed Remove references to deprecated functions in \sa statements Fixes: QTBUG-94534 Pick-to: 6.2 Change-Id: I3b3d4277d63fc5d6d207c28ff2484aed30b83247 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>