• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1[/
2          Copyright Oliver Kowalke 2013.
3 Distributed under the Boost Software License, Version 1.0.
4    (See accompanying file LICENSE_1_0.txt or copy at
5          http://www.boost.org/LICENSE_1_0.txt
6]
7
8[section:future Future]
9
10A future provides a mechanism to access the result of an asynchronous operation.
11
12[#shared_state]
13[heading shared state]
14
15Behind a [template_link promise] and its [template_link future] lies an
16unspecified object called their ['shared state]. The shared state is what will
17actually hold the async result (or the exception).
18
19The shared state is instantiated along with the [template_link promise].
20
21Aside from its originating `promise<>`, a [template_link future] holds a
22unique reference to a particular shared state. However, multiple
23[template_link shared_future] instances can reference the same underlying
24shared state.
25
26As [template_link packaged_task] and [ns_function_link fibers..async] are
27implemented using [template_link promise], discussions of shared state apply
28to them as well.
29
30[#class_future_status]
31[heading Enumeration `future_status`]
32
33Timed wait-operations (__wait_for__ and __wait_until__) return the state of the future.
34
35        enum class future_status {
36            ready,
37            timeout,
38            deferred  // not supported yet
39        };
40
41[heading `ready`]
42[variablelist
43[[Effects:] [The [link shared_state shared state] is ready.]]
44]
45
46[heading `timeout`]
47[variablelist
48[[Effects:] [The [link shared_state shared state] did not become ready before timeout has passed.]]
49]
50
51[note Deferred futures are not supported.]
52
53
54[template_heading future]
55
56A __future__ contains a [link shared_state shared state] which is not shared with any other future.
57
58        #include <boost/fiber/future/future.hpp>
59
60        namespace boost {
61        namespace fibers {
62
63        template< typename R >
64        class future {
65        public:
66            future() noexcept;
67
68            future( future const& other) = delete;
69
70            future & operator=( future const& other) = delete;
71
72            future( future && other) noexcept;
73
74            future & operator=( future && other) noexcept;
75
76            ~future();
77
78            bool valid() const noexcept;
79
80            shared_future< R > share();
81
82            R get();    // member only of generic future template
83            R & get();  // member only of future< R & > template specialization
84            void get(); // member only of future< void > template specialization
85
86            std::exception_ptr get_exception_ptr();
87
88            void wait() const;
89
90            template< class Rep, class Period >
91            future_status wait_for(
92                std::chrono::duration< Rep, Period > const& timeout_duration) const;
93
94            template< typename Clock, typename Duration >
95            future_status wait_until(
96                std::chrono::time_point< Clock, Duration > const& timeout_time) const;
97        };
98
99        }}
100
101[heading Default constructor]
102
103        future() noexcept;
104
105[template future_ctor_variablelist[xfuture]
106[variablelist
107[[Effects:] [Creates a [xfuture] with no [link shared_state shared state].
108After construction `false == valid()`.]]
109[[Throws:] [Nothing.]]
110]
111]
112[future_ctor_variablelist future]
113
114[heading Move constructor]
115
116        future( future && other) noexcept;
117
118[template future_move_copy_ctor_variablelist[xfuture post_valid]
119[variablelist
120[[Effects:] [Constructs a [xfuture] with the [link shared_state shared state] of other.
121After construction [post_valid].]]
122[[Throws:] [Nothing.]]
123]
124]
125[future_move_copy_ctor_variablelist future..`false == other.valid()`]
126
127[heading Destructor]
128
129        ~future();
130
131[template future_dtor_variablelist[xfuture end]
132[variablelist
133[[Effects:] [Destroys the [xfuture]; ownership is abandoned[end]]]
134[[Note:] [[`~[xfuture]()] does ['not] block the calling fiber.]]
135]
136]
137[future_dtor_variablelist future .]
138
139Consider a sequence such as:
140
141# instantiate [template_link promise]
142# obtain its `future<>` via [member_link promise..get_future]
143# launch [class_link fiber], capturing `promise<>`
144# destroy `future<>`
145# call [member_link promise..set_value]
146
147The final `set_value()` call succeeds, but the value is silently discarded: no
148additional `future<>` can be obtained from that `promise<>`.
149
150[operator_heading future..operator_assign..operator=]
151
152        future & operator=( future && other) noexcept;
153
154[variablelist
155[[Effects:] [Moves the [link shared_state shared state] of other to `this`.
156After the assignment, `false == other.valid()`.]]
157[[Throws:] [Nothing.]]
158]
159
160[template future_valid[xfuture]
161[member_heading [xfuture]..valid]
162
163        bool valid() const noexcept;
164
165[variablelist
166[[Effects:] [Returns `true` if [xfuture] contains a [link shared_state shared state].]]
167[[Throws:] [Nothing.]]
168]
169]
170[future_valid future]
171
172[member_heading future..share]
173
174        shared_future< R > share();
175
176[variablelist
177[[Effects:] [Move the state to a __shared_future__.]]
178[[Returns:] [a __shared_future__ containing the [link shared_state shared
179state] formerly belonging to `*this`.]]
180[[Postcondition:] [`false == valid()`]]
181[[Throws:] [__future_error__ with error condition __no_state__.]]
182]
183
184[template future_method_wait[end] Waits until [member_link promise..set_value] or
185[member_link promise..set_exception] is called[end]]
186
187[member_heading future..get]
188
189        R get();    // member only of generic future template
190        R & get();  // member only of future< R & > template specialization
191        void get(); // member only of future< void > template specialization
192
193[template future_get_variablelist[]
194[variablelist
195[[Precondition:] [`true == valid()`]]
196[[Returns:] [[future_method_wait .] If [member_link promise..set_value] is
197called, returns the value. If [member_link promise..set_exception] is called,
198throws the indicated exception.]]
199[[Postcondition:] [`false == valid()`]]
200[[Throws:] [__future_error__ with error condition __no_state__,
201__broken_promise__. Any exception passed to
202`promise::set_exception()`.]]
203]
204]
205[future_get_variablelist]
206
207[template future_get_exception_ptr[xfuture]
208[member_heading [xfuture]..get_exception_ptr]
209
210        std::exception_ptr get_exception_ptr();
211
212[variablelist
213[[Precondition:] [`true == valid()`]]
214[[Returns:] [[future_method_wait .] If `set_value()` is called, returns a
215default-constructed `std::exception_ptr`. If `set_exception()` is called,
216returns the passed `std::exception_ptr`.]]
217[[Throws:] [__future_error__ with error condition __no_state__.]]
218[[Note:] [ `get_exception_ptr()` does ['not] invalidate the [`[xfuture]].
219After calling `get_exception_ptr()`, you may still call [member_link
220[xfuture]..get].]]
221]
222]
223[future_get_exception_ptr future]
224
225[template future_wait_etc[xfuture]
226[member_heading [xfuture]..wait]
227
228        void wait();
229
230[variablelist
231[[Effects:] [[future_method_wait .]]]
232[[Throws:] [__future_error__ with error condition __no_state__.]]
233]
234
235[template_member_heading [xfuture]..wait_for]
236
237        template< class Rep, class Period >
238        future_status wait_for( std::chrono::duration< Rep, Period > const& timeout_duration) const;
239
240[variablelist
241[[Effects:] [[future_method_wait , or `timeout_duration` has passed.]]]
242[[Result:] [A `future_status` is returned indicating the reason for returning.]]
243[[Throws:] [__future_error__ with error condition __no_state__ or
244timeout-related exceptions.]]
245]
246
247[template_member_heading [xfuture]..wait_until]
248
249        template< typename Clock, typename Duration >
250        future_status wait_until( std::chrono::time_point< Clock, Duration > const& timeout_time) const;
251
252[variablelist
253[[Effects:] [[future_method_wait , or `timeout_time` has passed.]]]
254[[Result:] [A `future_status` is returned indicating the reason for returning.]]
255[[Throws:] [__future_error__ with error condition __no_state__ or
256timeout-related exceptions.]]
257]
258]
259[future_wait_etc future]
260
261
262[template_heading shared_future]
263
264A __shared_future__ contains a [link shared_state shared state] which might be
265shared with other __shared_future__ instances.
266
267        #include <boost/fiber/future/future.hpp>
268
269        namespace boost {
270        namespace fibers {
271
272        template< typename R >
273        class shared_future {
274        public:
275            shared_future() noexcept;
276
277            ~shared_future();
278
279            shared_future( shared_future const& other);
280
281            shared_future( future< R > && other) noexcept;
282
283            shared_future( shared_future && other) noexcept;
284
285            shared_future & operator=( shared_future && other) noexcept;
286
287            shared_future & operator=( future< R > && other) noexcept;
288
289            shared_future & operator=( shared_future const& other) noexcept;
290
291            bool valid() const noexcept;
292
293            R const& get(); // member only of generic shared_future template
294            R & get();      // member only of shared_future< R & > template specialization
295            void get();     // member only of shared_future< void > template specialization
296
297            std::exception_ptr get_exception_ptr();
298
299            void wait() const;
300
301            template< class Rep, class Period >
302            future_status wait_for(
303                std::chrono::duration< Rep, Period > const& timeout_duration) const;
304
305            template< typename Clock, typename Duration >
306            future_status wait_until(
307                std::chrono::time_point< Clock, Duration > const& timeout_time) const;
308        };
309
310        }}
311
312[heading Default constructor]
313
314        shared_future();
315
316[future_ctor_variablelist shared_future]
317
318[heading Move constructor]
319
320        shared_future( future< R > && other) noexcept;
321        shared_future( shared_future && other) noexcept;
322
323[future_move_copy_ctor_variablelist shared_future..`false == other.valid()`]
324
325[heading Copy constructor]
326
327        shared_future( shared_future const& other) noexcept;
328
329[future_move_copy_ctor_variablelist shared_future..`other.valid()` is unchanged]
330
331[heading Destructor]
332
333        ~shared_future();
334
335[future_dtor_variablelist shared_future.. if not shared.]
336
337[operator_heading shared_future..operator_assign..operator=]
338
339        shared_future & operator=( future< R > && other) noexcept;
340        shared_future & operator=( shared_future && other) noexcept;
341        shared_future & operator=( shared_future const& other) noexcept;
342
343[variablelist
344[[Effects:] [Moves or copies the [link shared_state shared state] of other to
345`this`. After the assignment, the state of `other.valid()` depends on which
346overload was invoked: unchanged for the overload accepting `shared_future
347const&`, otherwise `false`.]]
348[[Throws:] [Nothing.]]
349]
350
351[future_valid shared_future]
352
353[member_heading shared_future..get]
354
355        R const& get(); // member only of generic shared_future template
356        R & get();      // member only of shared_future< R & > template specialization
357        void get();     // member only of shared_future< void > template specialization
358
359[future_get_variablelist]
360
361[future_get_exception_ptr shared_future]
362
363[future_wait_etc shared_future]
364
365[ns_function_heading fibers..async]
366
367        #include <boost/fiber/future/async.hpp>
368
369        namespace boost {
370        namespace fibers {
371
372        template< class Function, class ... Args >
373        future<
374            std::result_of_t<
375                std::decay_t< Function >( std::decay_t< Args > ... )
376            >
377        >
378        async( Function && fn, Args && ... args);
379
380        template< class Function, class ... Args >
381        future<
382            std::result_of_t<
383                std::decay_t< Function >( std::decay_t< Args > ... )
384            >
385        >
386        async( ``[link class_launch `launch`]`` policy, Function && fn, Args && ... args);
387
388        template< typename __StackAllocator__, class Function, class ... Args >
389        future<
390            std::result_of_t<
391                std::decay_t< Function >( std::decay_t< Args > ... )
392            >
393        >
394        async( ``[link class_launch `launch`]`` policy, __allocator_arg_t__, __StackAllocator__ salloc,
395               Function && fn, Args && ... args);
396
397        template< typename __StackAllocator__, typename Allocator, class Function, class ... Args >
398        future<
399            std::result_of_t<
400                std::decay_t< Function >( std::decay_t< Args > ... )
401            >
402        >
403        async( ``[link class_launch `launch`]`` policy, __allocator_arg_t__, __StackAllocator__ salloc,
404               Allocator alloc, Function && fn, Args && ... args);
405
406        }}
407
408[variablelist
409[[Effects:] [Executes `fn` in a [class_link fiber] and returns an associated
410[template_link future].]]
411[[Result:] [``future<
412    std::result_of_t<
413        std::decay_t< Function >( std::decay_t< Args > ... )
414    >
415>`` representing the [link
416shared_state shared state] associated with the asynchronous execution of
417`fn`.]]
418[[Throws:] [__fiber_error__ or __future_error__ if an error occurs.]]
419[[Notes:] [The overloads accepting __allocator_arg_t__ use the passed
420__StackAllocator__ when constructing the launched `fiber`. The overloads
421accepting [class_link launch] use the passed `launch` when
422constructing the launched `fiber`. The default `launch` is `post`, as
423for the `fiber` constructor.]]
424]
425
426[note Deferred futures are not supported.]
427
428[endsect]
429