summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qfuture_impl.h
Commit message (Collapse)AuthorAgeFilesLines
* QtPrivate::Continuation: add missing Q_DISABLE_COPY(_MOVE)Marc Mutz2024-05-031-0/+1
| | | | | | | | | | | | This polymorphic class is not designed for copying or moving, so statically assert that it isn't moved or copied. Amends dfaca09e85a49d2983bb89893bfbe1ba4c19eab4. Pick-to: 6.7 Task-number: QTBUG-124909 Change-Id: I6a4fe460adf9bf903578601e500ccc697a3f7c96 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* qfuture_impl.h: remove redundant declarationMarc Mutz2024-05-011-3/+0
| | | | | | | | | | | | | | | QtPrivate::watchContinuationImpl() is already declared in qfutureinterface.h, which qfuture_impl.h already includes. Fixes GCC -Wredundant-decls. Amends 59e21a536f7f81625216dc7a621e7be59919da33. Pick-to: 6.7 Task-number: QTBUG-115583 Change-Id: I9c77209d2d10492f4d81aacc1f1da3201b5d1810 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Arno Rehn <a.rehn@menlosystems.com>
* Doc: Change deprecation of QFuture::makeReadyFuture to 6.6Kai Köhne2023-12-041-2/+2
| | | | | | | | | | | | | | | | | The compilers will only warn about using makeValueFuture from Qt 6.10 onwards. Anyhow, for the documentation, it makes more sense to deprecate it right now, as an alternative API is available. So deprecate in documentation for Qt 6.6, but mention that the compiler warning will only be shown in Qt 6.10. While at it, also make sure the deprecation messages are proper sentences (end with a dot). Pick-to: 6.6 Fixes: QTBUG-116898 Change-Id: Iff90441372b788f9ea42634866d97068275bf0ca Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* qfuture_impl.h: remove unused qpointer.h includeMarc Mutz2023-10-051-1/+0
| | | | | | | | The last QPointer user was removed in commit 07d6d31a4c0c17d8c897d783a9b0841df6834b02. Prune the include. Change-Id: Id48ffd2f8f5c1790bbdc54d66ac0c404b0af9cd2 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* QFuture: fix headercheck warning with Clang 17: member shadowingThiago Macieira2023-09-261-11/+11
| | | | | | | | | | | | Pretty sure this is a Clang bug because the promise member that it says is getting shadowed shouldn't be in scope (`this` isn't being captured). qfuture_impl.h:538:60: error: declaration shadows a field of 'Continuation<Function, ResultType, ParentResultType>' [-Werror,-Wshadow] qfuture_impl.h:327:26: note: previous declaration is here Pick-to: 6.5 6.6 Change-Id: Ifeb6206a9fa04424964bfffd17883e21cfec6d8e Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* QtFuture: Prevent whenAll()/whenAny() from creating reference cyclesArno Rehn2023-09-151-6/+9
| | | | | | | | | | | | whenAll() and whenAny() create a shared context object which is referenced by the continuation lambda. The refcount of context is only correctly managed when it is copied non-const to the lambda's capture list. Fixes: QTBUG-116731 Pick-to: 6.6 6.6.0 Change-Id: I8e79e1a0dc867f69bbacf1ed873f353a18f6ad38 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Move QBasicFutureWatcher behind the ABI boundaryMarc Mutz2023-07-131-1/+0
| | | | | | | | | | | | ... and out of QtPrivate. No inline API requires it anymore, so move it into the only TU using it. Can't move it into the unnamed namespace because of the friend declaration in QFutureInterfaceBase. Pick-to: 6.6 Change-Id: I27452960492bc1193a4d0eaeb2acd913d4dd02a5 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* QFuture: Extract Method watchContinuation() (DRY && SCARY)Marc Mutz2023-07-131-22/+15
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The old code violated the following principles: - DRY: the same code occurred 3× in the code-base - SCARY: the vast majority doesn't actually depend on template arguments, causing template bloat Solve both with a tiered Extract Method. We cannot change the order of the operations performed on QBasicFutureWatcher, in particular not the connect() to the contination w.r.t. setFuture(), so we cannot leave the connect to the continuation lambda outside the function, as it would mean to also leave the setFuture() call outside. Thanks to Volker's makeCallableObject(), we can, however, type-erase the lambda using QSlotObjectBase, which is what connect() internally creates, anyway, therefore bringing the whole function behind the ABI boundary. As a non-QObject, non-QMetaObject friend, we're lacking support for actually doing something useful with a QSlotObjectBase, but that can be fixed in the implementation now. The interface is stable, which is what matters for 6.6 now. This will allow a subsequent commit to drag QBasicFutureWatcher behind the ABI boundary, unexporting it. Saves a whopping 8KiB in tst_qfuture text size on optimized C++20 Linux AMD64 GCC9 builds. Pick-to: 6.6 Done-with: Fabian Kosmale <fabian.kosmale@qt.io> Change-Id: I0e5c2564907d92f6938689ab249be11fc0332ba5 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Arno Rehn <a.rehn@menlosystems.com> Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QPromise: Propagate cancellation through failure handlersArno Rehn2023-06-201-0/+2
| | | | | | | | | | | | | | | Previously, failure handlers did not propagate cancellation. This would lead to crashes when a QPromise was cancelled without having generated any result. Subsequent continuations would be invoked and try to access the result (which was nonexistent) and then crash. This patch propagates cancellation through failure handlers to prevent subsequent continuations from being called in the first place. Fixes: QTBUG-114606 Pick-to: 6.6 Pick-to: 6.5 Change-Id: I23b28a8e70a76e1ba6416be4440360c6dbaef2a3 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* QFuture: Gracefully handle a destroyed context in continuationsArno Rehn2023-05-301-40/+45
| | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch relaxes the requirements on the context object of continuations. Instead of having to stay alive during execution of the whole chain, it now only has to stay alive during setup of the chain. If the context object is destroyed before the chain finishes, the respective future is canceled. This patch works by using QFutureCallOutInterface and signals instead of direct invocation of the continuation by the parent future, similar to how QFutureWatcher is implemented. If a continuation is used with a context object, a QBasicFutureWatcher is connected to the QFuture via a QFutureCallOutInterface. When the future finishes, QBasicFutureWatcher::finished() triggers the continuation with a signal/slot connection. This way, we require the context object to stay alive only during setup; the required synchronization is guaranteed by the existing event and signal-slot mechanisms. The continuation itself does not need to know about the context object anymore. [ChangeLog][QtCore][QFuture] Added support for context objects of continuations being destroyed before the continuation finishes. In these cases the future is cancelled immediately. Fixes: QTBUG-112958 Change-Id: Ie0ef3470b2a0ccfa789d2ae7604b92e509c14591 Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* Deprecate QtFuture::makeReadyFuture()Ivan Solovev2023-04-051-0/+4
| | | | | | | | | | | | | | | | | | | [ChangeLog][Deprecation Notice][QtCore] The QtFuture::makeReadyFuture() method and all its specializations are deprecated since Qt 6.10. The reason for the deprecation is that the method has a makeReadyFuture(const QList<T> &) overload, which behaves differently from all other overloads (including other non-const ref QList overloads). Use QtFuture::makeReadyVoidFuture() when you need a ready void QFuture, or QtFuture::makeReadyValueFuture() when you need to propagate the input type to the returned QFuture, or QtFuture::makeReadyRangeFuture() when you need to create a multi-value future based on an input container. Fixes: QTBUG-109677 Change-Id: I55125269989df0a02840d5ddd5763ef5f1070df5 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Long live QtFuture::makeReadyVoidFuture() and QtFuture::makeReadyValueFuture()Ivan Solovev2023-04-051-15/+12
| | | | | | | | | | | | | | | | [ChangeLog][QtCore][QFuture] Added QtFuture::makeReadyVoidFuture() and QtFuture::makeReadyValueFuture(). Basically, these methods behave like QtFuture::makeReadyFuture(), but QtFuture::makeReadyValueFuture() does not have a "const QList<T> &" specialization returning QFuture<T> instead of QFuture<QList<T>>, which allows it to always behave consistently. This patch also introduces usage of the new methods around qtbase. Task-number: QTBUG-109677 Change-Id: I89df8b26d82c192baad69efb5df517a8b182995f Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Long live QtFuture::makeReadyRangeFuture()Ivan Solovev2023-04-051-6/+46
| | | | | | | | | | | | | | | | [ChangeLog][QtCore][QFuture] Introduce QtFuture::makeReadyRangeFuture(). This method takes a container which has input iterators and returns a multi-value QFuture<ValueType>, where ValueType is the underlying type of the input container. This commit also replaces the usage of buggy QtFuture::makeReadyFuture(const QList<T> &) overload with the new method. Task-number: QTBUG-109677 Change-Id: I019e62eac74c643d88a65b3cc0085bc7c33bc712 Reviewed-by: Marc Mutz <marc.mutz@qt.io>
* Fix crash when cancelling a QFuture that has continuation with contextSona Kurazyan2023-01-061-6/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | To support cancellation of continuations attached via the parent future, we store a pointer to continuation future's data in parent. This requires preserving the lifetime of continuation future's data while the parent is still alive (see 24dedaeaa1a94bfe9ade2da2a2c9aa112241b07a). This is achieved by capturing the promise in the continuation's lambda, which is only cleaned up after the parent's data is destroyed. This is already the case for continuations without context, but was overlooked for continuations with context: they transfer the ownership of the continuation promise to lambda passed to QMetaObject::invokeMethod(), which destroys the lambda's context after it's run. As a result, the continuation's promise (and data, if there are no other copies of it) is also destroyed, leaving the parent pointing to deleted continuation data. To fix this, capture a copy of continuation future's ref-counted data in the continuation's lambda. This will guarantee that the continuation data remains alive until the parent is destroyed and the continuation is cleaned up. Fixes: QTBUG-108790 Pick-to: 6.5 6.4 6.2 Change-Id: Ief4b37f31e652988d13b03499505ac65c7889226 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* QFuture: port from QSharedPointer to std::shared_ptrMarc Mutz2022-12-221-6/+8
| | | | | | | | | | | | | | | | | | | | Compared to std::shared_ptr, QSharedPointer requires 2x the atomic operations per copy, and this code uses _a lot_ of copies. Port to std::shared_ptr. The uses are all in inline, non-exported code, so there's no BC or SC issue here. Old code will happily continue to use its QSharedPointer-based code, while recompiled code will enjoy the transparent efficiency gain. This also helps prepare QtCore for an eventual QT_NO_SHARED_POINTER (which QtCore will not be able to set on itself, because QPointer is still not ported away from QWeakPointer, but which should affect as few headers as possible). Pick-to: 6.5 Change-Id: I8159c38d93f3bcfc22a236c8c26541ab5ee4e6d0 Reviewed-by: Sona Kurazyan <kurazyan.sona@gmail.com> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Replace usages of Q_CLANG_QDOC with Q_QDOCLuca Di Sera2022-10-211-1/+1
| | | | | | | | | | | | | | | | | | | | | | | To allow the user to customize the C++ code that QDoc sees, so as to be able to work-around some limitations on QDoc itself, QDoc defines two symbols: Q_QDOC and Q_CLANG_QDOC, both of which are "true" during an entire execution of QDoc. At a certain point in time, QDoc allowed the user the choice between a custom C++ parser and a Clang based one. The Q_QDOC symbol would always be defined while the Q_CLANG_QDOC symbol would be defined only when the Clang based parser was chosen. In more recent times, QDoc always uses a Clang based parser, such that both Q_CLANG_QDOC and Q_QDOC are always defined, making them equivalent. To avoid using different symbols, and the possible confusion and fragmentation that derives from it, all usages of Q_CLANG_QDOC are now replaced by the equivalent usages of Q_QDOC. Change-Id: I5810abb9ad1016a4c5bbea99acd03381b8514b3f Reviewed-by: Kai Koehne <kai.koehne@qt.io>
* Fix typos in docs and commentsKai Köhne2022-06-151-2/+2
| | | | | | | | | Found by codespell Pick-to: 6.4 Change-Id: Ie3e301a23830c773a2e9aff487c702a223d246eb Reviewed-by: Nicholas Bennett <nicholas.bennett@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Use SPDX license identifiersLucie Gérard2022-05-161-38/+2
| | | | | | | | | | | | | Replace the current license disclaimer in files by a SPDX-License-Identifier. Files that have to be modified by hand are modified. License files are organized under LICENSES directory. Task-number: QTBUG-67283 Change-Id: Id880c92784c40f3bbde861c0d93f58151c18b9f1 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Jörg Bornemann <joerg.bornemann@qt.io>
* Add support for unwrapping QFuture<QFuture<T>>Sona Kurazyan2022-04-211-0/+53
| | | | | | | | | | | | | | | | Added QFuture::unwrap() for unwrapping the future nested inside QFuture<QFuture<T>>. QTBUG-86725 suggests doing the unwrapping automatically inside .then(), but this will change the return type of .then() that used to return QFuture<QFuture<T>> and might cause SC breaks. Apart from that, QFuture::unwrap() might be helpful in general, for asynchronous computations that return a nested QFuture. [ChangeLog][QtCore][QFuture] Added QFuture::unwrap() for unwrapping the future nested inside QFuture<QFuture<T>>. Task-number: QTBUG-86725 Change-Id: I8886743aca261dca46f62d9dfcaead4a141d3dc4 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* WhenAllContext: optimize atomic operationsMarc Mutz2022-04-051-4/+5
| | | | | | | | | | | | | | | | | | The old code performed one load-acquire (in the assertion) and one ordered(!) fetch_sub() (in the pre-decrement operator) where one relaxed fetch_sub() would suffice (it's just a counter). Fix by caching the result of the relaxed fetch_sub() and performing the following checks on the cached result. As drive-bys, rename the atomic member variable (to catch any outside uses) and make the ctor explicit. Found by locally disabling the QAtomic<T> -> T implicit conversion operators. Change-Id: Ifdc11c2c4807b71f4cab2ba9f5405ace7d8d71a9 Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
* QFuture: fix a codechecker warningSona Kurazyan2022-03-221-1/+1
| | | | | | | | | | | | Codechecker complains about passing a forwarding reference to std::move, which may unexpectedly cause lvalues to be moved. We should use std::forward instead. This amends cbf8fc0ac43365f4dd69c64ec770d8f547d772f3 Change-Id: Ieba9e960b5dfb448e9cebabe9541967698995b8f Reviewed-by: Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* Fix warning in tst_qfutureVolker Hilsheimer2022-03-211-1/+1
| | | | | | | | | | | | | | | Explicitly move the argument into the return value to silence: qfuture_impl.h:153:20: warning: local variable 'arg' will be copied despite being returned by name [-Wreturn-std-move] return arg; ^~~ [...] qfuture_impl.h:153:20: note: call 'std::move' explicitly to avoid copying Change-Id: I49fab7c31efb7d809182c8d56e6a5ed8f05a5622 Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
* QFuture: fix QtFuture::connect corner-casesGiuseppe D'Angelo2022-03-171-0/+11
| | | | | | | | | | | | | | Connecting to nullptr, or connecting to a non-signal PMF, would result in a QFuture which would never finish. Catch these cases and handle them. Windows+MSVC for some reason fails the test. I can't entirely understand why, so I've marked it as XFAIL, with QTBUG-101761 to track it. Change-Id: I314980e7e9b7156d8cddd3b33d5cbf1d0bcd6116 Pick-to: 6.2 6.3 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
* QtFuture::connect: fix for signals with a single std::tuple argumentSona Kurazyan2022-01-311-12/+1
| | | | | | | | | | | | | | | | | | | If the signal passed to QtFuture::connect() takes multiple arguments, we need to wrap the arguments in a std::tuple when reporting the result. To detect this case we were checking if the result type of a QFuture returned by QtFuture::connect() is a std::tuple, but this was not correct: the result type could be a std::tuple also if the passed signal takes a single std::tuple argument. Instead, check if the signal takes more than one argument. As a drive-by modified the tst_QFuture::signalConnect to use const values for tuples used in multiple test-cases, to avoid repetition. Fixes: QTBUG-100071 Pick-to: 6.2 6.3 Change-Id: I1ce39cf87028f36ef94a9d1a4423b0c51473afd4 Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
* QFuture: add a missing include for qpromise.hSona Kurazyan2022-01-241-4/+1
| | | | | | | | | | | | | 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>
* Optimize ContinuationWrapper used for support of move-only continuationsSona Kurazyan2022-01-211-3/+11
| | | | | | | | | | | | | | | 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>
* 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>
* 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>
* Add support for combining multiple QFuturesSona Kurazyan2021-11-201-0/+189
| | | | | | | | | | | [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>
* QFuture: support cancellation of continuation chain through parentSona Kurazyan2021-11-131-4/+4
| | | | | | | | | | | | | | | | | | | 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>
* QFuture: put the result store and the exception store in a unionSona Kurazyan2021-06-121-5/+7
| | | | | | | | | | | | | | QFuture doesn't need both at the same time, calling QFuture::result(s) either returns a result or throws an exception. Store result and exception stores in a union, to reduce the memory. Also added a note for making the ResultStoreBase destructor non-virtual in Qt 7. Task-number: QTBUG-92045 Change-Id: I7f0ac03804d19cc67c1a1466c7a1365219768a14 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QtFuture::connect: disconnect signals firstMårten Nordheim2021-04-121-7/+7
| | | | | | | | | | During reportFinished we may call a continuation which might end up triggering one of the signals. Pick-to: 6.0 6.1 Change-Id: I19546fcca12be71cd536e4287eb5eddd9d236830 Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Add support of invoking QFuture continuations in a given contextSona Kurazyan2020-12-111-19/+101
| | | | | | | | | | | | Added overloads of .then()/.onFailed()/.onCanceled() which take a pointer of a context object, and invoke the continuations in the object's thread. Task-number: QTBUG-86794 Change-Id: I0f3cbb0500695673fc4087af5d4b96b416e3e1ce Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
* Fix memory leaks in QFuture's continuationsSona Kurazyan2020-12-011-22/+28
| | | | | | | | | | | | | | | | | | | | | | | | | | | There were two issues: - Some of the continuations were allocating memory for the continuation's context dynamically, but deleting the allocated memory only if they were actually invoked. Since the continuations may not be invoked at all, this could cause memory leaks. Fixed by postponing the allocations to the point when the continuations need to be invoked. - In other cases the parent future is captured by copy in the continuation's lambda, which is then saved in the parent. This causes the following problem: the data of the ref-counted parent will be deleted as soon as its last copy gets deleted. But the saved continuation will prevent it from being deleted, since it holds a copy of parent. To break the circular dependency, instead of capturing the parent inside the lambda, we can pass the parent's data directly to continuation when calling it. Fixes: QTBUG-87289 Change-Id: If340520b68f6e960bc80953ca18b796173d34f7b Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Ivan Solovev <ivan.solovev@qt.io> Reviewed-by: Karsten Heimrich <karsten.heimrich@qt.io> (cherry picked from commit 5d26d40a5596be048be87f309df9264bac741be9) Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
* Fix perfect forwarding of callables in QFuture's continuationsSona Kurazyan2020-12-011-24/+34
| | | | | | | | | | | | Use universal references instead of rvalue references for passing callables in the implementations of QFuture's continuations. Change-Id: I1288c78f78f84f30c6607e505e7f9807a9272071 Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Ivan Solovev <ivan.solovev@qt.io> Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io> (cherry picked from commit b002722dabef794da0e80010b115b2c6cd6dc6b8) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
* Add convenience functions for QFuture creationIvan Solovev2020-11-231-0/+63
| | | | | | | | | | [ChangeLog][QtCore][QFuture] Add convenience functions to create a ready QFuture and a QFuture with an exception Task-number: QTBUG-86713 Change-Id: Ic7f9ca590a8ea8a9696b84f35bad074780794461 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
* QtConcurrent: Integrate runWithPromise into runJarek Kobus2020-10-281-3/+3
| | | | | | Change-Id: I6eb95aa66ff847e8bb9aac348fded3a5d55015b6 Reviewed-by: Paul Wicking <paul.wicking@qt.io> Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
* QtConcurrent: Reuse ArgResolver from qfuture_impl.hJarek Kobus2020-10-261-0/+46
| | | | | | Task-number: QTBUG-83331 Change-Id: I572f68f6d3be4a50970d8d77d070f175be3ec785 Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
* Add QPromise implementationAndrei Golubev2020-06-091-0/+4
| | | | | | | | | | | | | | | | | | | | | | QPromise and QFuture created from it share the same internal state (namely, QFutureInterface object). QPromise provides high-level management of the shared resource, ensuring thread-safe behavior on construction and destruction (also taking into account QFuture::waitForFinished() semantics). QFuture acts as a primary controller of QPromise via action initiating methods such as suspend() or cancel(). QPromise is equipped with methods to check the status, but the actual handling of QFuture action "requests" is user-defined. [ChangeLog][QtCore][QPromise] Added QPromise class to accompany QFuture. It allows one to communicate computation results and progress to the QFuture via a shared state. Task-number: QTBUG-81586 Change-Id: Ibab9681d35fe63754bf394ad0e7923e2683e2457 Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Add support of cancellation handler callbacks to QFutureSona Kurazyan2020-05-151-12/+63
| | | | | | | | | Added QFuture::onCanceled() method, for attaching handlers to be called when the QFuture gets canceled. Change-Id: I1f01647d6173ba0c1db6641e14140108b33ac7c4 Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Add support of connecting signals to QFutureSona Kurazyan2020-05-151-0/+78
| | | | | | | | | | | Introduced QtFuture::connect(sender, signal) function returning a QFuture object, which is resolved when the signal is emitted. Task-number: QTBUG-81589 Change-Id: Idbe301eb247b468b9b34f3470c3359d6a7af2f3a Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Make continuations work with move-only typesSona Kurazyan2020-04-181-26/+78
| | | | | | | | | | Use the move-only versions of result reporting and getting operations, if the type of QFuture is not copyable. Task-number: QTBUG-81941 Change-Id: Ic9fa978380e2c24e190e68d974051a650b0e5571 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Vitaly Fanaskov <vitaly.fanaskov@qt.io>
* Add support of failure handler callbacks to QFutureSona Kurazyan2020-04-011-1/+174
| | | | | | | | | Added QFuture::onFailed() method, which allows attaching handlers for exceptions that may occur in QFuture continuation chains. Task-number: QTBUG-81588 Change-Id: Iadeee99e3a7573207f6ca9f650ff9f7b6faa2cf7 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Store QFuture exceptions as std::exception_ptrSona Kurazyan2020-04-011-5/+2
| | | | | | | | | | | Replaced the internal ExceptionHolder for storing QException* by std::exception_ptr. This will allow to report and store exceptions of types that are not derived from QException. Task-number: QTBUG-81588 Change-Id: I96be919d8289448b3e608310e51a16cebc586301 Reviewed-by: Vitaly Fanaskov <vitaly.fanaskov@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* Clean-up the duplicate code in QFuture and QFutureWatcherSona Kurazyan2020-03-231-0/+6
| | | | | | | | | | | | QFuture<void> and QFutureWatcher<void> are specialized to not contain any of result fetching methods, but otherwise they share almost the same implementation with QFuture<T> and QFutureWatcher<T> respectively. This change unifies their implementations to get rid of unnecessary code duplication. Change-Id: I9494ddc58c6db192c66edb988105927da6d61a3b Reviewed-by: Vitaly Fanaskov <vitaly.fanaskov@qt.io>
* Add support for attaching continuations to QFutureSona Kurazyan2020-03-051-0/+339
Added QFuture::then() methods to allow chaining multiple asynchronous computations. Continuations can use the following execution policies: * QtFuture::Launch::Sync - the continuation will be launched in the same thread in which the parent has been executing. * QtFuture::Launch::Async - the continuation will be launched in a new thread. * QtFuture::Launch::Inherit - the continuation will inherit the launch policy of the parent, or its thread pool (if it was using a custom one). * Additionally then() also accepts a custom QThreadPool* instance. Note, that if the parent future gets canceled, its continuation(s) will be also canceled. If the parent throws an exception, it will be propagated to the continuation's future, unless it is caught inside the continuation (if it has a QFuture arg). Some example usages: QFuture<int> future = ...; future.then([](int res1){ ... }).then([](int res2){ ... })... QFuture<int> future = ...; future.then([](QFuture<int> fut1){ /* do something with fut1 */ })... In the examples above all continuations will run in the same thread as future. QFuture<int> future = ...; future.then(QtFuture::Launch::Async, [](int res1){ ... }) .then([](int res2){ ... }).. In this example the continuations will run in a new thread (but on the same one). QThreadPool pool; QFuture<int> future = ...; future.then(&pool, [](int res1){ ... }) .then([](int res2){ ... }).. In this example the continuations will run in the given thread pool. [ChangeLog][QtCore] Added support for attaching continuations to QFuture. Task-number: QTBUG-81587 Change-Id: I5b2e176694f7ae8ce00404aca725e9a170818955 Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>