summaryrefslogtreecommitdiffstats
path: root/src/corelib/thread/qpromise.qdoc
blob: 09907c4e0e7f3a566551cb8e138f040ff47302cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
// Copyright (C) 2020 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*! \class QPromise
    \inmodule QtCore
    \threadsafe
    \brief The QPromise class provides a way to store computation results to be accessed by QFuture.
    \since 6.0

    \ingroup thread

    QPromise provides a simple way to communicate progress and results of the
    user-defined computation to QFuture in an asynchronous fashion. For the
    communication to work, QFuture must be constructed by QPromise.

    You can use QPromise based workloads as an alternative to \l {Qt Concurrent}
    framework when fine-grained control is needed or high-level communication
    primitive to accompany QFuture is sufficient.

    The simplest case of promise and future collaboration would be a single
    result communication:

    \snippet snippet_qpromise.cpp basic

    By design, QPromise is a move-only object. This behavior helps to ensure
    that whenever the promise is destroyed, the associated future object is
    notified and will not wait forever for the results to become available.
    However, this is inconvenient if one wants to use the same promise to report
    results from different threads. There is no specific way to do that at the
    moment, but known mechanisms exist, such as the use of smart pointers or raw
    pointers/references. QSharedPointer is a good default choice if you want to
    copy your promise and use it in multiple places simultaneously. Raw pointers
    or references are, in a sense, easier, and probably perform better (since
    there is no need to do a resource management) but may lead to dangling.

    Here is an example of how a promise can be used in multiple threads:

    \snippet snippet_qpromise.cpp multithread_init
    \codeline
    \snippet snippet_qpromise.cpp multithread_main

    \sa QFuture
*/

/*! \fn template <typename T> QPromise<T>::QPromise()

    Constructs a QPromise with a default state.
*/

/*! \fn template <typename T> QPromise<T>::QPromise(QPromise<T> &&other)

    Move constructs a new QPromise from \a other.

    \sa operator=()
*/

/*! \fn template <typename T> QPromise<T>::QPromise(const QFutureInterface<T> &other)
    \fn template <typename T> QPromise<T>::QPromise(QFutureInterface<T> &&other) noexcept

    \internal
    Constructs a QPromise with a passed QFutureInterface \a other.
    Used internally for QtConcurrent::run(), when its callable takes
    a reference to the associated promise as its first argument
    (run with promise mode).

    \sa operator=()
*/


/*! \fn template <typename T> QPromise<T> &QPromise<T>::operator=(QPromise<T> &&other)

    Move assigns \a other to this promise and returns a reference to this
    promise.
*/

/*! \fn template <typename T> QPromise<T>::~QPromise()

    Destroys the promise.

    \note The promise implicitly transitions to a canceled state on destruction
    unless finish() is called beforehand by the user.
*/

/*! \fn template <typename T> QFuture<T> QPromise<T>::future() const

    Returns a future associated with this promise.
*/

/*! \fn template <typename T> bool QPromise<T>::addResult(const T &result, int index = -1)
    \fn template <typename T> bool QPromise<T>::addResult(T &&result, int index = -1)

    Adds \a result to the internal result collection at \a index position. If
    index is unspecified, \a result is added to the end of the collection.

    Returns \c true when \a result is added to the collection.

    Returns \c false when this promise is in canceled or finished state or when
    \a result is rejected. addResult() rejects \a result if there's already
    another result in the collection stored at the same index.

    You can get a result at a specific index by calling QFuture::resultAt().

    \note It is possible to specify an arbitrary index and request result at
    that index. However, some QFuture methods operate with continuous results.
    For instance, iterative approaches that use QFuture::resultCount() or
    QFuture::const_iterator. In order to get all available results without
    thinking if there are index gaps or not, use QFuture::results().
*/

/*! \fn template<typename T> void QPromise<T>::setException(const QException &e)

    Sets exception \a e to be the result of the computation.

    \note You can set at most one exception throughout the computation
    execution.

    \note This method must not be used after QFuture::cancel() or
    finish().

    \sa isCanceled()
*/

#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
/*! \fn template<typename T> void QPromise<T>::setException(std::exception_ptr e)

    \overload
*/
#else
/*! \fn template<typename T> void QPromise<T>::setException(const std::exception_ptr &e)

    \overload
*/
#endif

/*! \fn template<typename T> void QPromise<T>::start()

    Reports that the computation is started. Calling this method is important to
    state the beginning of the computation as QFuture methods rely on this
    information.

    \note Extra attention is required when start() is called from a
    newly created thread. In such case, the call might naturally be delayed due
    to the implementation details of the thread scheduling.

    \sa QFuture::isStarted(), QFuture::waitForFinished(), finish()
*/

/*! \fn template<typename T> void QPromise<T>::finish()

    Reports that the computation is finished. Once finished, no new results will
    be added when calling addResult(). This method accompanies start().

    \sa QFuture::isFinished(), QFuture::waitForFinished(), start()
*/

/*! \fn template<typename T> void QPromise<T>::suspendIfRequested()

    Conditionally suspends current thread of execution and waits until resumed
    or canceled by the corresponding methods of QFuture. This method does not
    block unless the computation is requested to be suspended by
    QFuture::suspend() or another related method. If you want to check that the
    execution has been suspended, use QFuture::isSuspended().

    \note When using the same promise in multiple threads,
    QFuture::isSuspended() becomes \c true as soon as at least one thread with
    the promise suspends.


    The following code snippets show the usage of suspension mechanism:

    \snippet snippet_qpromise.cpp suspend_start

    QFuture::suspend() requests the associated promise to suspend:

    \snippet snippet_qpromise.cpp suspend_suspend

    After QFuture::isSuspended() becomes \c true, you can get intermediate
    results:

    \snippet snippet_qpromise.cpp suspend_intermediateResults

    When suspended, you can resume or cancel the awaiting computation:

    \snippet snippet_qpromise.cpp suspend_end


    \sa QFuture::resume(), QFuture::cancel(), QFuture::setSuspended(),
    QFuture::toggleSuspended()
*/

/*! \fn template<typename T> bool QPromise<T>::isCanceled() const

    Returns whether the computation has been canceled with the
    QFuture::cancel() function. The returned value \c true indicates that the
    computation should be finished and finish() called.

    \note After cancellation, results currently available may still be accessed
    by a future, but new results will not be added when calling addResult().
*/

/*! \fn template<typename T> void QPromise<T>::setProgressRange(int minimum, int maximum)

    Sets the progress range of the computation to be between \a minimum and \a
    maximum.

    If \a maximum is smaller than \a minimum, \a minimum becomes the only
    legal value.

    The progress value is reset to be \a minimum.

    The progress range usage can be disabled by using setProgressRange(0, 0).
    In this case progress value is also reset to 0.

    \sa QFuture::progressMinimum(), QFuture::progressMaximum(),
    QFuture::progressValue()
*/

/*! \fn template<typename T> void QPromise<T>::setProgressValue(int progressValue)

    Sets the progress value of the computation to \a progressValue. It is
    possible to only increment the progress value. This is a convenience method
    for calling setProgressValueAndText(progressValue, QString()).

    In case of the \a progressValue falling out of the progress range,
    this method has no effect.

    \sa QFuture::progressValue(), setProgressRange()
*/

/*! \fn template<typename T> void QPromise<T>::setProgressValueAndText(int progressValue, const QString &progressText)

    Sets the progress value and the progress text of the computation to \a
    progressValue and \a progressText respectively. It is possible to only
    increment the progress value.

    \note This function has no effect if the promise is in canceled or finished
    state.

    \sa QFuture::progressValue(), QFuture::progressText(), QFuture::cancel(),
    finish()
*/

/*! \fn template<typename T> void QPromise<T>::swap(QPromise<T> &other) noexcept

    Swaps promise \a other with this promise. This operation is very fast and never fails.
*/