summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qfutureinterface.h
Commit message (Collapse)AuthorAgeFilesLines
* QFutureInterface: fix build with GCC14/C++20: template-id not allowedThiago Macieira2024-03-141-1/+1
| | | | | | | | | | | When declaring a constructor, you must use the injected name, not a template. qfutureinterface.h:472:37: error: template-id not allowed for constructor in C++20 [-Werror=template-id-cdtor] Pick-to: 6.6 6.7 Change-Id: I6818d78a57394e37857bfffd17bbbf2313001cbf Reviewed-by: Ahmad Samir <a.samirh78@gmail.com>
* QFuture: Don't use QFutureCallOutInterface for continuationsArno Rehn2023-12-131-2/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This patch replaces the QBasicFutureWatcher that was used for continuations with context objects with a smaller QObject-based wrapper that works directly from the actual continuation. The idea stays the same: In order to run continuations in the thread of a context object, we offload the continuation invocation to the signal-slot mechanism. Previously, we've hooked into QFuture with QFutureCallOutInterface to emit a signal and trigger continuation invocation. However, it is much easier and robust to emit that signal from the continuation itself. This sidesteps the locking issues that QFutureCallOutInterface handling presents. QFutureCallOutInterface basically requires any consumer to only access the QFuture after all events have been posted and the internal mutex unlocked, i.e. on the next cycle of the event loop. Continuations do not impose this restriction; runContinuation() explicitly unlocks the internal mutex before calling the continuation. This fixes a deadlock when using QFuture::then(context, ...) where the paren future is resolved from the same thread that the context object lives in. Fixes: QTBUG-119406 Fixes: QTBUG-119103 Fixes: QTBUG-117918 Fixes: QTBUG-119579 Fixes: QTBUG-119810 Pick-to: 6.7 6.6 Change-Id: I112b16024cde6b6ee0e4d8127392864b813df5bc Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
* Move QBasicFutureWatcher behind the ABI boundaryMarc Mutz2023-07-131-2/+2
| | | | | | | | | | | | ... 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: Gracefully handle a destroyed context in continuationsArno Rehn2023-05-301-0/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* QFutureInterface: Extract Method reportAndEmplaceResult() from ↵Marc Mutz2023-03-311-2/+11
| | | | | | | | | | reportAndMoveResult() This will be the building block for emplacement support in QPromise. Task-number: QTBUG-112270 Change-Id: Ie267e76fe078a8f7b3ef8c7e0d2abfcd22062ff2 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* QFutureInterface::reportAndMoveResult(): don't spell a move as forward<T>()Marc Mutz2023-03-311-1/+1
| | | | | | | | | | | | | | | The T&& result argument is not deduced (T is the template class' template argument, so it's an rvalue reference, not a Universal Reference, assuming that we don't support QFutureInterface<U> where U is a reference type). So std::forward<T> will always be a std::move(), so use that directly instead of raising eyebrows in the reader of the code by using forward<> to feed a function called _move_Result(). Pick-to: 6.5 Change-Id: I805df4686b5b74da57f8212b052b4056943a15fa Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* Port from container.count()/length() to size()Marc Mutz2022-10-041-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is semantic patch using ClangTidyTransformator: auto QtContainerClass = expr(hasType(namedDecl(hasAnyName(<classes>)))).bind(o) makeRule(cxxMemberCallExpr(on(QtContainerClass), callee(cxxMethodDecl(hasAnyName({"count", "length"), parameterCountIs(0))))), changeTo(cat(access(o, cat("size"), "()"))), cat("use 'size()' instead of 'count()/length()'")) a.k.a qt-port-to-std-compatible-api with config Scope: 'Container'. <classes> are: // sequential: "QByteArray", "QList", "QQueue", "QStack", "QString", "QVarLengthArray", "QVector", // associative: "QHash", "QMultiHash", "QMap", "QMultiMap", "QSet", // Qt has no QMultiSet Change-Id: Ibe8837be96e8d30d1846881ecd65180c1bc459af Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* QFuture: fix handling of cancelled continuation chainSona Kurazyan2022-09-211-2/+0
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | To support cancellation of continuations attached via the parent future, for each future returned by a continuation we store a pointer to its parent (i.e. future the continuation is attached to). Later, before executing a continuation, we go through chain of parents and check if any of them is cancelled. However, if one of the parents is destroyed while the chain is executing, the next continuations' parent pointers will become invalid. So storing the parent pointers isn't safe. This commit changes the logic of handling the cancelled continuation chain in the following way: - Instead of storing a parent pointer in the continuation future's data, we do the opposite: we store a pointer to continuation's future in the parent. - When a future is cancelled, we mark all continuation futures in the chain with a flag indicating that the chain is cancelled. - To guarantee that the pointers to continuation future's data don't become invalid, we clean the continuation (that stores a copy of its future's data and keeps it alive) only when the associated promise is destructed, instead of cleaning it after the continuation is run. Fixes: QTBUG-105182 Fixes: QTBUG-106083 Pick-to: 6.2 6.3 6.4 Change-Id: I48afa98152672c0fc737112be4ca3b1b42f6ed30 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Move QFutureInterfaceBase::cleanContinuation() to removed_apiSona Kurazyan2022-06-221-0/+2
| | | | | | | | | | This method isn't used anymore, but we can't remove it entirely for BC reasons, because it was called from inline code. Pick-to: 6.4 Change-Id: I9183c666c466030787ac7c2386706b50abf23eaa Reviewed-by: Marc Mutz <marc.mutz@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
* 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>
* Fix memory leaks when capturing a QFuture in its continuationSona Kurazyan2022-01-211-0/+4
| | | | | | | | | | | | | | | | | | | | | | 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>
* QFuture: support cancellation of continuation chain through parentSona Kurazyan2021-11-131-0/+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>
* Optimize QPromise destructorSona Kurazyan2021-10-081-0/+5
| | | | | | | | | 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>
* Add QFutureInterfaceBase::get() to retrieve internals of QFutureArno Rehn2021-07-121-0/+3
| | | | | | | | | | | | For generic interop with other parts of Qt, we need to be able to extract the type-erased internal storage of QFuture<T>. In particular, QtWebChannel needs this to transparently support QFuture<T> as a method return type. Task-number: QTBUG-92903 Change-Id: I763f054656b8810d58720262d364baf42c47eb37 Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
* QFutureInterface: remove the inconsistent and unneeded includeSona Kurazyan2021-06-251-1/+0
| | | | | | | | | QMutexLocker is declared in qmutex.h, which is already included. Pick-to: 6.2 Task-number: QTBUG-94407 Change-Id: I78e0630c27ef7f85feae68e98f8cdcbe4e142cd8 Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
* QFuture: put the result store and the exception store in a unionSona Kurazyan2021-06-121-1/+33
| | | | | | | | | | | | | | 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>
* QFutureInterface(Base): code tidiesGiuseppe D'Angelo2021-06-081-3/+4
| | | | | | | | | | | | | | | | refT()/derefT() can be marked noexcept; we don't care about not overflowing the refcounter as a precondition. (This is BC, as no compiler mangles noexcept.) This in turn allows to mark a constructor calling refT() as noexcept. Driveby: mark also the same functions to not be `const` in Qt 7. They clearly are meant to modify *this, and constness only works because of the unmanaged (raw) d-pointer. Change-Id: I8d7d365640ff2e1cedc0a234c9abccdfc95ba6e3 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
* QPromise/QFutureInterface: in Qt 7 take std::exception_ptr by const-refGiuseppe D'Angelo2021-06-081-0/+4
| | | | | | | | | | | std::exception_ptr is a reference-counted "smart pointer", so we shouldn't copy it around freely. Unfortunately QFutureInterface has exported functions taking it by value, so we can't just change the signatures and keep BC. Simply prepare the code for Qt 7. Change-Id: Ic5aae6a095c8c842872a40db440c99d2dfe371f1 Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io>
* QPromise/QFuture: fix value semanticsGiuseppe D'Angelo2021-05-221-10/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | In random order: * QFutureInterfaceBase has a d-pointer, and copy semantics. So, "naturally" extend it to support move semantics as well. (These get used by QPromise/QFuture, as they both hold a QFutureInterface* as a data member). The only addition needed is a check for a null d-pointer in the destructor. Drive by, reorganize the code for the copies, and use copy-and-swap instead of the hand-rolled solution. Also, add a free swap() overload, and mark the existing one as candidate for inlining in Qt 7 (doesn't need to be an exported function). * QFutureInterface inherits QFutureInterfaceBase, again with value semantics. To be honest, I'm not sure why QFutureInterfaceBase is polymorphic -- could be a design mistake, as polymorphic classes don't mix with value semantics. Anyways, reorganize the code for copies, apply copy-and-swap, and add move semantics. This requires adding a check into derefT(). * Finally, QPromise was already move-only, but had broken move semantics: the move constructor was not noexcept (!) and it actually allocated memory (!!!). Fix that one (can be defaulted now), and streamline the move assignment via the proper macro. Drive by, fix the signature of the constructor from QFutureInterface (take const-ref, not plain ref -- it's eventually copied, so it can keep the const), and add another internal constructor from rvalue QFutureInterface that moves from it. Change-Id: I9d61a9dd4d45f34942d8f34416baa118c0307390 Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
* QFuture: cleanup headersFabian Kosmale2021-03-221-13/+18
| | | | | | | | | | | | | | Do not include vector; we currently do not use std::vector, and the plan is to use QList when that one supports move-only types. Use QMutexLocker instead of std::mutex_locker, considering that the former is already included with <QMutex>. Use forward declarations where applicable. Add header which were currently only indirectly included (to make QtCreator's code model happy). Change-Id: I37d5cd3982047a6d8a3132fd66571878298039b3 Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io> Reviewed-by: Karsten Heimrich <karsten.heimrich@qt.io>
* Fix memory leaks in QFuture's continuationsSona Kurazyan2020-12-011-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* Make QPromise::addResult() return boolean status of operationAndrei Golubev2020-10-161-37/+45
| | | | | | | | | | | | | | | Changed QPromise::addResult() to return bool value. True is returned when result is added and false is returned when e.g. promise is in final state (canceled or finished) or when addResult() is called twice with the same index as argument (in which case new value is rejected) Updated QFutureInterface::reportFinished() that accepts optional result as argument to align with other result adding methods. This function is "internal" only (as of now), so no documentation update is needed Change-Id: I2d63069246e5e5c8cf04529c22bb296faaaae53d Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
* Reject overwrites by the same index in QPromise::addResult()Andrei Golubev2020-10-131-7/+10
| | | | | | | | | | | | One can call addResult(value, index) twice and consequently set the value twice by the same index. This seems rather strange and probably should not be allowed. This commit rejects setting results when there's already a valid result by that index. Consequently, this fixes memory leaks caused by N-times-called addResult(..., index) Fixes: QTBUG-86828 Change-Id: I77494f2cb73ce727ffad721cfcdcaa420899eb25 Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
* Temporarily disable QFuture::takeResult() methodSona Kurazyan2020-10-121-0/+5
| | | | | | | | | | | | QFuture::takeResult() currently returns std::vector instead of QList, because QList does not support move-only types. Disable this method until QList is fixed to work with move-only types in Qt 6.1. Also did minor doc-fixes. Change-Id: I87feaf75d9433a3b540edd00039c3e21d6994985 Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
* Introduce swap functions for QPromise/QFutureInterfaceAndrei Golubev2020-08-031-1/+9
| | | | | | | | | | Made QPromise::swap public, added free standing swap() for QFutureInterface and QPromise. Updated QPromise special member functions. Extended tests Task-number: QTBUG-84977 Change-Id: I5daf6876df306d082441dbcdf5ae4dee3bfc0ead Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
* Use QList instead of QVector in corelibJarek Kobus2020-06-251-4/+4
| | | | | | | | | | Applied to headers only. Source file to be changed separately. Omitted statemachine for now to avoid conflicts. Omitted qmetatype.h for now - to be handled later. Task-number: QTBUG-84469 Change-Id: I317376037a62467c313467d92955ad0b7473aa97 Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
* Add QPromise implementationAndrei Golubev2020-06-091-0/+9
| | | | | | | | | | | | | | | | | | | | | | 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>
* Deprecate the pause-related APIs of QFuture* classesSona Kurazyan2020-06-041-11/+21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | Deprecated the pause-related APIs of QFuture* classes and added alternatives having "suspend" in the name instead. With 2f15927f01ceef0aca490746302a5ea57ea9441c new isSuspended()/suspended() APIs have been added to QFuture* classes for checking if pause/suspension is still in progress or it already took effect. To keep the naming more consistent, renamed: - setPaused() -> setSuspended() - pause() -> suspend() - togglePaused() -> toggleSuspended() - QFutureWatcher::paused() -> QFutureWatcher::suspending() Note that QFuture*::isPaused() now corresponds to (isSuspending() || isSuspended()). [ChangeLog][Deprecation Notice] Deprecated pause-related APIs of QFuture and QFutureWatcher. Added alternatives having "suspend" in the name instead. Change-Id: Ibeb75017a118401d64d18b72fb95d78e28c4661c Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io> Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io> Reviewed-by: Andrei Golubev <andrei.golubev@qt.io> Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
* Add a way of notifying QFutureWatcher when pause is in effectSona Kurazyan2020-05-291-1/+4
| | | | | | | | | | | | | | | | | | | | | | | | Because setting QFutureInterface to paused state does not mean that the computations that are already in progress will stop immediately, it may be useful to get notified when pause actually takes effect. Introduced the QFutureWatcher::suspended() signal, to be emitted when there are no more computations in progress, and no more result ready or progress reporting signals will be emitted, i.e. when pause took effect. Added {QFuture, QFutureWatcher}::isSuspended() methods for checking if pause took effect. QtConcurrent will now to send QFutureCallOutEvent::Suspended event when the state is paused and there are no more active threads. [ChangeLog][QtCore][QFutureWatcher] Added a new QFutureWatcher::suspended() signal, to be emitted when pause took effect, meaning that there are no more computations in progress. Added {QFuture, QFutureWatcher}::isSuspended() methods for checking if pause took effect. Fixes: QTBUG-12152 Change-Id: I88f2ad24d800cd6293dec63977d45bd35f9a09f0 Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
* Add support of cancellation handler callbacks to QFutureSona Kurazyan2020-05-151-0/+6
| | | | | | | | | 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>
* QFuture: the result type doesn't have to be a default-constructibleVitaly Fanaskov2020-04-231-13/+2
| | | | | | | | | | | Added asserts to insure the invariant declared in the documentation. Canceled future object is not valid, hence we don't need to handle this case separately. Fixes: QTBUG-83389 Change-Id: Ib0653ef40cd3135574a91740e4ce2c6dc4da8a71 Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io> Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
* Add support of failure handler callbacks to QFutureSona Kurazyan2020-04-011-0/+10
| | | | | | | | | 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-0/+1
| | | | | | | | | | | 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>
* QFuture - add ability to move results from QFutureTimur Pocheptsov2020-03-311-4/+82
| | | | | | | | | | | | | | | | | | | | | | | | | | | | QFuture's original design pre-dates C++11 and its introduction of move semantics. QFuture is documented as requiring copy-constructible classes and uses copy operations for results (which in Qt's universe in general is relatively cheap, due to the use of COW/data sharing). QFuture::result(), QFuture::results(), QFuture::resultAt() return copies. Now that the year is 2020, it makes some sense to add support for move semantics and, in particular, move-only types, like std::unique_ptr (that cannot be obtained from QFuture using result etc.). Taking a result or results from a QFuture renders it invalid. This patch adds QFuture<T>::takeResults(), takeResult() and isValid(). 'Taking' functions are 'enabled_if' for non-void types only to improve the compiler's diagnostic (which would otherwise spit some semi-articulate diagnostic). As a bonus a bug was found in the pre-existing code (after initially copy and pasted into the new function) - the one where we incorrectly report ready results in (rather obscure) filter mode. Fixes: QTBUG-81941 Fixes: QTBUG-83182 Change-Id: I8ccdfc50aa310a3a79eef2cdc55f5ea210f889c3 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
* Add support for attaching continuations to QFutureSona Kurazyan2020-03-051-2/+27
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | 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>
* QFutureInterface: clean up mutex() method for Qt 6Marc Mutz2019-09-121-7/+6
| | | | | | | | | | | | | | Ditch the QMutex *mutex() method that we had to keep around for binary compatibility and drop the disambiguation argument of QMutex &mutex(int) now that we don't need it anymore. The lock_guard lines now look dangerously close to C++'s Most Vexing Parse, so use braced initialization to make sure it's parsed as a definition, not a declaration. Change-Id: Ie3d70f58c9878ab6d7da8f8bd72a4cb4aff83bb7 Reviewed-by: Edward Welbourne <edward.welbourne@qt.io> Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
* Port away from QMutexLocker in public headersMarc Mutz2019-08-251-5/+8
| | | | | | | | | | | | | | | | | We can't use qt_scoped_lock/qt_unique_lock here, so port to std::unique_lock and std::lock_guard for now. This is in preparation of deprecating QMutexLocker in favor of std::unique_lock and std::scoped_lock. In QFutureInterface, change the return type of mutex() from QMutex* to QMutex&, so we don't need to deref when passing to std::lock_guard. We need to keep the old method around for BC reasons, so the new one needs an artificial function argument for disambiguation. This will vanish come Qt 6. Change-Id: I1a0f0205952a249512ec2dbd3f0f48dd209b1636 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* QFutureInterface::reportFinished use nullptr instead of 0Albert Astals Cid2018-07-051-1/+1
| | | | | | | | So that users don't get a warning if using -Wzero-as-null-pointer-constant Change-Id: Ia15b5f380a2f6a93e05eec06646608e480cdf5d2 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Make QT_NO_FUTURE a featureUlf Hermann2017-12-191-4/+2
| | | | | | | | | | | ... and make sure we can compile without it. In particular, Qt Concurrent depends on QFuture, so we specify it as a condition, and QtConcurrentException should not depend on future but on concurrent. Change-Id: I65b158021cecb19f227554cc8b5df7a139fbfe78 Reviewed-by: Martin Smith <martin.smith@qt.io> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
* Replace Q_NULLPTR with nullptr where possibleKevin Funk2017-09-191-1/+1
| | | | | | | | | | | | | Remaining uses of Q_NULLPTR are in: src/corelib/global/qcompilerdetection.h (definition and documentation of Q_NULLPTR) tests/manual/qcursor/qcursorhighdpi/main.cpp (a test executable compilable both under Qt4 and Qt5) Change-Id: If6b074d91486e9b784138f4514f5c6d072acda9a Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
* Fix UB in QFutureInterface: invalid casts from ResultStoreBase to ResultStore<>Olivier Goffart2017-03-061-17/+11
| | | | | | | | | | | ResultStore never actually exists, only ResutStoreBase does. So casting to ResultStore<T> and calling its member functions is UB. Put the type dependent function as template member functions within ResultStoreBase and so we don't need QtPrivate::ResultStore anymore. Same goes for the iterator. Change-Id: I739b9d234ba2238977863df77fde3a4471a9abd2 Reviewed-by: Marc Mutz <marc.mutz@kdab.com>
* QFuture(Interface): remove unneeded special member functionsMarc Mutz2016-08-131-9/+1
| | | | | | | | | | | | | | | | | | The compiler-generated ones are just fine. This is BC because the class is not exported and QFutureInterfaceBase (needlessly) contains virtual functions (the dtor), so this class will never be trivially copyable. It's also not movable, until I figure out how to add move special member functions to QFutureInterfaceBase. Also made the QFutureInterface(State) constructor explicit, because a State is not a faithful representation of a QFutureInterface. Change-Id: Ifa44f87b41c4ee3c5167c282512ec4860075671d Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Updated license headersJani Heikkinen2016-01-151-14/+20
| | | | | | | | | | | From Qt 5.7 -> LGPL v2.1 isn't an option anymore, see http://blog.qt.io/blog/2016/01/13/new-agreement-with-the-kde-free-qt-foundation/ Updated license headers to use new LGPL header instead of LGPL21 one (in those files which will be under LGPL v3) Change-Id: I046ec3e47b1876cd7b4b0353a576b352e3a946d9 Reviewed-by: Lars Knoll <lars.knoll@theqtcompany.com>
* QtCore: Use Q_NULLPTR instead of 0 in all public headersMarc Mutz2015-07-011-1/+1
| | | | | | | | | This is in preparation of adding -Wzero-as-null-pointer-constant (or similar) to the headers check. Task-number: QTBUG-45291 Change-Id: I0cc388ef9faf45cbcf425ad0dc77db3060c104a8 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
* Update copyright headersJani Heikkinen2015-02-111-7/+7
| | | | | | | | | | | | | | | | | | Qt copyrights are now in The Qt Company, so we could update the source code headers accordingly. In the same go we should also fix the links to point to qt.io. Outdated header.LGPL removed (use header.LGPL21 instead) Old header.LGPL3 renamed to header.LGPL3-COMM to match actual licensing combination. New header.LGPL-COMM taken in the use file which were using old header.LGPL3 (src/plugins/platforms/android/extract.cpp) Added new header.LGPL3 containing Commercial + LGPLv3 + GPLv2 license combination Change-Id: I6f49b819a8a20cc4f88b794a8f6726d975e8ffbe Reviewed-by: Matti Paaso <matti.paaso@theqtcompany.com>
* Update license headers and add new license filesMatti Paaso2014-09-241-19/+11
| | | | | | | | | - Renamed LICENSE.LGPL to LICENSE.LGPLv21 - Added LICENSE.LGPLv3 - Removed LICENSE.GPL Change-Id: Iec3406e3eb3f133be549092015cefe33d259a3f2 Reviewed-by: Iikka Eklund <iikka.eklund@digia.com>
* QFutureInterface: allow to work with a QThreadPool != globalInstance()Marc Mutz2014-08-051-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Background: It is often necessary/advisable to schedule tasks on thread pools != globalInstance(). As Herb Sutter writes in http://www.drdobbs.com/parallel/use-thread-pools-correctly-keep-tasks-sh/216500409 and the Qt Training Material stresses, tasks you schedule on a (global) thread pool should be non-blocking, which currently rules out using any of the QtConcurrent functions for, say, file I/O. Nonetheless it's often convenient to have thread pools also for file I/O, as the thumbnail viewer exercise in the Qt Training Material shows. In this case, you'd use a dedicated thead pool, leaving the global thread pool for CPU-bound tasks. Yet, none of the QtConcurrent functions allow to pick the QThreadPool instance on which to schedule the work created with them. This patch prepares for them to do so. This is the first part of the forward-port of https://qt.gitorious.org/qt/qt/merge_requests/1281. Implement by using a new QThreadPool* member that defaults to nullptr, and adding setThreadPool to set this member, then using it in lieu of QThreadPool::globalInstance() everywhere. I chose to leave m_pool == nullptr to mean globalInstance() to avoid creating the global instance whenever a QFuture is created, even if the future represents the result of a calculation not run on the global thread pool. [ChangeLog][QtCore][QFuture] Can now be used with any QThreadPool, not just globalInstance(). Task-number: QTBUG-17220 Change-Id: I4e1dc18d55cf60141b2fa3d14e2d44a3e9e74858 Reviewed-by: Olivier Goffart <ogoffart@woboq.com>
* Whitespace cleanup: remove trailing whitespaceAxel Waggershauser2013-03-161-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | Remove all trailing whitespace from the following list of files: *.cpp *.h *.conf *.qdoc *.pro *.pri *.mm *.rc *.pl *.qps *.xpm *.txt *README excluding 3rdparty, test-data and auto generated code. Note A): the only non 3rdparty c++-files that still have trailing whitespace after this change are: * src/corelib/codecs/cp949codetbl_p.h * src/corelib/codecs/qjpunicode.cpp * src/corelib/codecs/qbig5codec.cpp * src/corelib/xml/qxmlstream_p.h * src/tools/qdoc/qmlparser/qqmljsgrammar.cpp * src/tools/uic/ui4.cpp * tests/auto/other/qtokenautomaton/tokenizers/* * tests/benchmarks/corelib/tools/qstring/data.cpp * util/lexgen/tokenizer.cpp Note B): in about 30 files some overlapping 'leading tab' and 'TAB character in non-leading whitespace' issues have been fixed to make the sanity bot happy. Plus some general ws-fixes here and there as asked for during review. Change-Id: Ia713113c34d82442d6ce4d93d8b1cf545075d11d Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
* Remove QT_{BEGIN,END}_HEADER macro usageSergio Ahumada2013-01-291-3/+0
| | | | | | | | | | | The macro was made empty in ba3dc5f3b56d1fab6fe37fe7ae08096d7dc68bcb and is no longer necessary or used. Discussed-on: http://lists.qt-project.org/pipermail/development/2013-January/009284.html Change-Id: Id2bb2e2cabde059305d4af5f12593344ba30f001 Reviewed-by: Laszlo Papp <lpapp@kde.org> Reviewed-by: Jędrzej Nowacki <jedrzej.nowacki@digia.com> Reviewed-by: hjk <hjk121@nokiamail.com>
* Update copyright year in Digia's license headersSergio Ahumada2013-01-181-1/+1
| | | | | Change-Id: Ic804938fc352291d011800d21e549c10acac66fb Reviewed-by: Lars Knoll <lars.knoll@digia.com>