Line data Source code
1 : // <future> -*- C++ -*-
2 :
3 : // Copyright (C) 2009-2021 Free Software Foundation, Inc.
4 : //
5 : // This file is part of the GNU ISO C++ Library. This library is free
6 : // software; you can redistribute it and/or modify it under the
7 : // terms of the GNU General Public License as published by the
8 : // Free Software Foundation; either version 3, or (at your option)
9 : // any later version.
10 :
11 : // This library is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 :
16 : // Under Section 7 of GPL version 3, you are granted additional
17 : // permissions described in the GCC Runtime Library Exception, version
18 : // 3.1, as published by the Free Software Foundation.
19 :
20 : // You should have received a copy of the GNU General Public License and
21 : // a copy of the GCC Runtime Library Exception along with this program;
22 : // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
23 : // <http://www.gnu.org/licenses/>.
24 :
25 : /** @file include/future
26 : * This is a Standard C++ Library header.
27 : */
28 :
29 : #ifndef _GLIBCXX_FUTURE
30 : #define _GLIBCXX_FUTURE 1
31 :
32 : #pragma GCC system_header
33 :
34 : #if __cplusplus < 201103L
35 : # include <bits/c++0x_warning.h>
36 : #else
37 :
38 : #include <mutex> // call_once
39 : #include <condition_variable> // __at_thread_exit_elt
40 : #include <system_error>
41 : #include <atomic>
42 : #include <bits/allocated_ptr.h>
43 : #include <bits/atomic_futex.h>
44 : #include <bits/invoke.h>
45 : #include <bits/unique_ptr.h>
46 : #include <bits/shared_ptr.h>
47 : #include <bits/std_function.h>
48 : #include <bits/std_thread.h>
49 : #include <bits/uses_allocator.h>
50 : #include <ext/aligned_buffer.h>
51 :
52 : namespace std _GLIBCXX_VISIBILITY(default)
53 : {
54 : _GLIBCXX_BEGIN_NAMESPACE_VERSION
55 :
56 : /**
57 : * @defgroup futures Futures
58 : * @ingroup concurrency
59 : *
60 : * Classes for futures support.
61 : * @{
62 : */
63 :
64 : /// Error code for futures
65 : enum class future_errc
66 : {
67 : future_already_retrieved = 1,
68 : promise_already_satisfied,
69 : no_state,
70 : broken_promise
71 : };
72 :
73 : /// Specialization.
74 : template<>
75 : struct is_error_code_enum<future_errc> : public true_type { };
76 :
77 : /// Points to a statically-allocated object derived from error_category.
78 : const error_category&
79 : future_category() noexcept;
80 :
81 : /// Overload for make_error_code.
82 : inline error_code
83 0 : make_error_code(future_errc __errc) noexcept
84 0 : { return error_code(static_cast<int>(__errc), future_category()); }
85 :
86 : /// Overload for make_error_condition.
87 : inline error_condition
88 : make_error_condition(future_errc __errc) noexcept
89 : { return error_condition(static_cast<int>(__errc), future_category()); }
90 :
91 : /**
92 : * @brief Exception type thrown by futures.
93 : * @ingroup exceptions
94 : */
95 : class future_error : public logic_error
96 : {
97 : public:
98 : explicit
99 0 : future_error(future_errc __errc)
100 0 : : future_error(std::make_error_code(__errc))
101 0 : { }
102 :
103 : virtual ~future_error() noexcept;
104 :
105 : virtual const char*
106 : what() const noexcept;
107 :
108 : const error_code&
109 : code() const noexcept { return _M_code; }
110 :
111 : private:
112 : explicit
113 0 : future_error(error_code __ec)
114 0 : : logic_error("std::future_error: " + __ec.message()), _M_code(__ec)
115 0 : { }
116 :
117 : friend void __throw_future_error(int);
118 :
119 : error_code _M_code;
120 : };
121 :
122 : // Forward declarations.
123 : template<typename _Res>
124 : class future;
125 :
126 : template<typename _Res>
127 : class shared_future;
128 :
129 : template<typename _Signature>
130 : class packaged_task;
131 :
132 : template<typename _Res>
133 : class promise;
134 :
135 : /// Launch code for futures
136 : enum class launch
137 : {
138 : async = 1,
139 : deferred = 2
140 : };
141 :
142 : constexpr launch operator&(launch __x, launch __y) noexcept
143 : {
144 : return static_cast<launch>(
145 : static_cast<int>(__x) & static_cast<int>(__y));
146 : }
147 :
148 : constexpr launch operator|(launch __x, launch __y) noexcept
149 : {
150 : return static_cast<launch>(
151 : static_cast<int>(__x) | static_cast<int>(__y));
152 : }
153 :
154 : constexpr launch operator^(launch __x, launch __y) noexcept
155 : {
156 : return static_cast<launch>(
157 : static_cast<int>(__x) ^ static_cast<int>(__y));
158 : }
159 :
160 : constexpr launch operator~(launch __x) noexcept
161 : { return static_cast<launch>(~static_cast<int>(__x)); }
162 :
163 : inline launch& operator&=(launch& __x, launch __y) noexcept
164 : { return __x = __x & __y; }
165 :
166 : inline launch& operator|=(launch& __x, launch __y) noexcept
167 : { return __x = __x | __y; }
168 :
169 : inline launch& operator^=(launch& __x, launch __y) noexcept
170 : { return __x = __x ^ __y; }
171 :
172 : /// Status code for futures
173 : enum class future_status
174 : {
175 : ready,
176 : timeout,
177 : deferred
178 : };
179 :
180 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
181 : // 2021. Further incorrect usages of result_of
182 : template<typename _Fn, typename... _Args>
183 : using __async_result_of = typename __invoke_result<
184 : typename decay<_Fn>::type, typename decay<_Args>::type...>::type;
185 :
186 : template<typename _Fn, typename... _Args>
187 : future<__async_result_of<_Fn, _Args...>>
188 : async(launch __policy, _Fn&& __fn, _Args&&... __args);
189 :
190 : template<typename _Fn, typename... _Args>
191 : future<__async_result_of<_Fn, _Args...>>
192 : async(_Fn&& __fn, _Args&&... __args);
193 :
194 : #if defined(_GLIBCXX_HAS_GTHREADS)
195 :
196 : /// Base class and enclosing scope.
197 : struct __future_base
198 : {
199 : /// Base class for results.
200 : struct _Result_base
201 : {
202 : exception_ptr _M_error;
203 :
204 : _Result_base(const _Result_base&) = delete;
205 : _Result_base& operator=(const _Result_base&) = delete;
206 :
207 : // _M_destroy() allows derived classes to control deallocation
208 : virtual void _M_destroy() = 0;
209 :
210 : struct _Deleter
211 : {
212 9593 : void operator()(_Result_base* __fr) const { __fr->_M_destroy(); }
213 : };
214 :
215 : protected:
216 : _Result_base();
217 : virtual ~_Result_base();
218 : };
219 :
220 : /// A unique_ptr for result objects.
221 : template<typename _Res>
222 : using _Ptr = unique_ptr<_Res, _Result_base::_Deleter>;
223 :
224 : /// A result object that has storage for an object of type _Res.
225 : template<typename _Res>
226 : struct _Result : _Result_base
227 : {
228 : private:
229 : __gnu_cxx::__aligned_buffer<_Res> _M_storage;
230 : bool _M_initialized;
231 :
232 : public:
233 : typedef _Res result_type;
234 :
235 3030 : _Result() noexcept : _M_initialized() { }
236 :
237 6046 : ~_Result()
238 : {
239 3023 : if (_M_initialized)
240 2691 : _M_value().~_Res();
241 8737 : }
242 :
243 : // Return lvalue, future will add const or rvalue-reference
244 : _Res&
245 5595 : _M_value() noexcept { return *_M_storage._M_ptr(); }
246 :
247 : void
248 995 : _M_set(const _Res& __res)
249 : {
250 995 : ::new (_M_storage._M_addr()) _Res(__res);
251 995 : _M_initialized = true;
252 995 : }
253 :
254 : void
255 1703 : _M_set(_Res&& __res)
256 : {
257 1703 : ::new (_M_storage._M_addr()) _Res(std::move(__res));
258 1703 : _M_initialized = true;
259 1703 : }
260 :
261 : private:
262 3023 : void _M_destroy() { delete this; }
263 : };
264 :
265 : /// A result object that uses an allocator.
266 : template<typename _Res, typename _Alloc>
267 : struct _Result_alloc final : _Result<_Res>, _Alloc
268 : {
269 : using __allocator_type = __alloc_rebind<_Alloc, _Result_alloc>;
270 :
271 : explicit
272 : _Result_alloc(const _Alloc& __a) : _Result<_Res>(), _Alloc(__a)
273 : { }
274 :
275 : private:
276 : void _M_destroy()
277 : {
278 : __allocator_type __a(*this);
279 : __allocated_ptr<__allocator_type> __guard_ptr{ __a, this };
280 : this->~_Result_alloc();
281 : }
282 : };
283 :
284 : // Create a result object that uses an allocator.
285 : template<typename _Res, typename _Allocator>
286 : static _Ptr<_Result_alloc<_Res, _Allocator>>
287 : _S_allocate_result(const _Allocator& __a)
288 : {
289 : using __result_type = _Result_alloc<_Res, _Allocator>;
290 : typename __result_type::__allocator_type __a2(__a);
291 : auto __guard = std::__allocate_guarded(__a2);
292 : __result_type* __p = ::new((void*)__guard.get()) __result_type{__a};
293 : __guard = nullptr;
294 : return _Ptr<__result_type>(__p);
295 : }
296 :
297 : // Keep it simple for std::allocator.
298 : template<typename _Res, typename _Tp>
299 : static _Ptr<_Result<_Res>>
300 : _S_allocate_result(const std::allocator<_Tp>& __a)
301 : {
302 : return _Ptr<_Result<_Res>>(new _Result<_Res>);
303 : }
304 :
305 : // Base class for various types of shared state created by an
306 : // asynchronous provider (such as a std::promise) and shared with one
307 : // or more associated futures.
308 : class _State_baseV2
309 : {
310 : typedef _Ptr<_Result_base> _Ptr_type;
311 :
312 : enum _Status : unsigned {
313 : __not_ready,
314 : __ready
315 : };
316 :
317 : _Ptr_type _M_result;
318 : __atomic_futex_unsigned<> _M_status;
319 : atomic_flag _M_retrieved = ATOMIC_FLAG_INIT;
320 : once_flag _M_once;
321 :
322 : public:
323 3030 : _State_baseV2() noexcept : _M_result(), _M_status(_Status::__not_ready)
324 3030 : { }
325 : _State_baseV2(const _State_baseV2&) = delete;
326 : _State_baseV2& operator=(const _State_baseV2&) = delete;
327 9593 : virtual ~_State_baseV2() = default;
328 :
329 : _Result_base&
330 4050 : wait()
331 : {
332 : // Run any deferred function or join any asynchronous thread:
333 4050 : _M_complete_async();
334 : // Acquire MO makes sure this synchronizes with the thread that made
335 : // the future ready.
336 4050 : _M_status._M_load_when_equal(_Status::__ready, memory_order_acquire);
337 4050 : return *_M_result;
338 : }
339 :
340 : template<typename _Rep, typename _Period>
341 : future_status
342 293 : wait_for(const chrono::duration<_Rep, _Period>& __rel)
343 : {
344 : // First, check if the future has been made ready. Use acquire MO
345 : // to synchronize with the thread that made it ready.
346 586 : if (_M_status._M_load(memory_order_acquire) == _Status::__ready)
347 258 : return future_status::ready;
348 :
349 35 : if (_M_is_deferred_future())
350 0 : return future_status::deferred;
351 :
352 : // Don't wait unless the relative time is greater than zero.
353 35 : if (__rel > __rel.zero()
354 70 : && _M_status._M_load_when_equal_for(_Status::__ready,
355 : memory_order_acquire,
356 : __rel))
357 : {
358 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
359 : // 2100. timed waiting functions must also join
360 : // This call is a no-op by default except on an async future,
361 : // in which case the async thread is joined. It's also not a
362 : // no-op for a deferred future, but such a future will never
363 : // reach this point because it returns future_status::deferred
364 : // instead of waiting for the future to become ready (see
365 : // above). Async futures synchronize in this call, so we need
366 : // no further synchronization here.
367 35 : _M_complete_async();
368 :
369 35 : return future_status::ready;
370 : }
371 0 : return future_status::timeout;
372 : }
373 :
374 : template<typename _Clock, typename _Duration>
375 : future_status
376 : wait_until(const chrono::time_point<_Clock, _Duration>& __abs)
377 : {
378 : #if __cplusplus > 201703L
379 : static_assert(chrono::is_clock_v<_Clock>);
380 : #endif
381 : // First, check if the future has been made ready. Use acquire MO
382 : // to synchronize with the thread that made it ready.
383 : if (_M_status._M_load(memory_order_acquire) == _Status::__ready)
384 : return future_status::ready;
385 :
386 : if (_M_is_deferred_future())
387 : return future_status::deferred;
388 :
389 : if (_M_status._M_load_when_equal_until(_Status::__ready,
390 : memory_order_acquire,
391 : __abs))
392 : {
393 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
394 : // 2100. timed waiting functions must also join
395 : // See wait_for(...) above.
396 : _M_complete_async();
397 :
398 : return future_status::ready;
399 : }
400 : return future_status::timeout;
401 : }
402 :
403 : // Provide a result to the shared state and make it ready.
404 : // Calls at most once: _M_result = __res();
405 : void
406 2698 : _M_set_result(function<_Ptr_type()> __res, bool __ignore_failure = false)
407 : {
408 2698 : bool __did_set = false;
409 : // all calls to this function are serialized,
410 : // side-effects of invoking __res only happen once
411 0 : call_once(_M_once, &_State_baseV2::_M_do_set, this,
412 2698 : std::__addressof(__res), std::__addressof(__did_set));
413 2698 : if (__did_set)
414 : // Use release MO to synchronize with observers of the ready state.
415 2698 : _M_status._M_store_notify_all(_Status::__ready,
416 : memory_order_release);
417 0 : else if (!__ignore_failure)
418 0 : __throw_future_error(int(future_errc::promise_already_satisfied));
419 2698 : }
420 :
421 : // Provide a result to the shared state but delay making it ready
422 : // until the calling thread exits.
423 : // Calls at most once: _M_result = __res();
424 : void
425 : _M_set_delayed_result(function<_Ptr_type()> __res,
426 : weak_ptr<_State_baseV2> __self)
427 : {
428 : bool __did_set = false;
429 : unique_ptr<_Make_ready> __mr{new _Make_ready};
430 : // all calls to this function are serialized,
431 : // side-effects of invoking __res only happen once
432 : call_once(_M_once, &_State_baseV2::_M_do_set, this,
433 : std::__addressof(__res), std::__addressof(__did_set));
434 : if (!__did_set)
435 : __throw_future_error(int(future_errc::promise_already_satisfied));
436 : __mr->_M_shared_state = std::move(__self);
437 : __mr->_M_set();
438 : __mr.release();
439 : }
440 :
441 : // Abandon this shared state.
442 : void
443 1267 : _M_break_promise(_Ptr_type __res)
444 : {
445 1267 : if (static_cast<bool>(__res))
446 : {
447 0 : __res->_M_error =
448 0 : make_exception_ptr(future_error(future_errc::broken_promise));
449 : // This function is only called when the last asynchronous result
450 : // provider is abandoning this shared state, so noone can be
451 : // trying to make the shared state ready at the same time, and
452 : // we can access _M_result directly instead of through call_once.
453 0 : _M_result.swap(__res);
454 : // Use release MO to synchronize with observers of the ready state.
455 0 : _M_status._M_store_notify_all(_Status::__ready,
456 : memory_order_release);
457 : }
458 1267 : }
459 :
460 : // Called when this object is first passed to a future.
461 : void
462 2698 : _M_set_retrieved_flag()
463 : {
464 5396 : if (_M_retrieved.test_and_set())
465 0 : __throw_future_error(int(future_errc::future_already_retrieved));
466 2698 : }
467 :
468 : template<typename _Res, typename _Arg>
469 : struct _Setter;
470 :
471 : // set lvalues
472 : template<typename _Res, typename _Arg>
473 : struct _Setter<_Res, _Arg&>
474 : {
475 : // check this is only used by promise<R>::set_value(const R&)
476 : // or promise<R&>::set_value(R&)
477 : static_assert(is_same<_Res, _Arg&>::value // promise<R&>
478 : || is_same<const _Res, _Arg>::value, // promise<R>
479 : "Invalid specialisation");
480 :
481 : // Used by std::promise to copy construct the result.
482 995 : typename promise<_Res>::_Ptr_type operator()() const
483 : {
484 995 : _M_promise->_M_storage->_M_set(*_M_arg);
485 995 : return std::move(_M_promise->_M_storage);
486 : }
487 : promise<_Res>* _M_promise;
488 : _Arg* _M_arg;
489 : };
490 :
491 : // set rvalues
492 : template<typename _Res>
493 : struct _Setter<_Res, _Res&&>
494 : {
495 : // Used by std::promise to move construct the result.
496 1703 : typename promise<_Res>::_Ptr_type operator()() const
497 : {
498 1703 : _M_promise->_M_storage->_M_set(std::move(*_M_arg));
499 1703 : return std::move(_M_promise->_M_storage);
500 : }
501 : promise<_Res>* _M_promise;
502 : _Res* _M_arg;
503 : };
504 :
505 : // set void
506 : template<typename _Res>
507 : struct _Setter<_Res, void>
508 : {
509 : static_assert(is_void<_Res>::value, "Only used for promise<void>");
510 :
511 : typename promise<_Res>::_Ptr_type operator()() const
512 : { return std::move(_M_promise->_M_storage); }
513 :
514 : promise<_Res>* _M_promise;
515 : };
516 :
517 : struct __exception_ptr_tag { };
518 :
519 : // set exceptions
520 : template<typename _Res>
521 : struct _Setter<_Res, __exception_ptr_tag>
522 : {
523 : // Used by std::promise to store an exception as the result.
524 0 : typename promise<_Res>::_Ptr_type operator()() const
525 : {
526 0 : _M_promise->_M_storage->_M_error = *_M_ex;
527 0 : return std::move(_M_promise->_M_storage);
528 : }
529 :
530 : promise<_Res>* _M_promise;
531 : exception_ptr* _M_ex;
532 : };
533 :
534 : template<typename _Res, typename _Arg>
535 : __attribute__((__always_inline__))
536 : static _Setter<_Res, _Arg&&>
537 : __setter(promise<_Res>* __prom, _Arg&& __arg) noexcept
538 : {
539 2698 : return _Setter<_Res, _Arg&&>{ __prom, std::__addressof(__arg) };
540 : }
541 :
542 : template<typename _Res>
543 : __attribute__((__always_inline__))
544 : static _Setter<_Res, __exception_ptr_tag>
545 : __setter(exception_ptr& __ex, promise<_Res>* __prom) noexcept
546 : {
547 0 : return _Setter<_Res, __exception_ptr_tag>{ __prom, &__ex };
548 : }
549 :
550 : template<typename _Res>
551 : __attribute__((__always_inline__))
552 : static _Setter<_Res, void>
553 : __setter(promise<_Res>* __prom) noexcept
554 : {
555 : return _Setter<_Res, void>{ __prom };
556 : }
557 :
558 : template<typename _Tp>
559 : static void
560 9739 : _S_check(const shared_ptr<_Tp>& __p)
561 : {
562 9739 : if (!static_cast<bool>(__p))
563 0 : __throw_future_error((int)future_errc::no_state);
564 9739 : }
565 :
566 : private:
567 : // The function invoked with std::call_once(_M_once, ...).
568 : void
569 9268 : _M_do_set(function<_Ptr_type()>* __f, bool* __did_set)
570 : {
571 9268 : _Ptr_type __res = (*__f)();
572 : // Notify the caller that we did try to set; if we do not throw an
573 : // exception, the caller will be aware that it did set (e.g., see
574 : // _M_set_result).
575 9268 : *__did_set = true;
576 9268 : _M_result.swap(__res); // nothrow
577 9268 : }
578 :
579 : // Wait for completion of async function.
580 5491 : virtual void _M_complete_async() { }
581 :
582 : // Return true if state corresponds to a deferred function.
583 35 : virtual bool _M_is_deferred_future() const { return false; }
584 :
585 : struct _Make_ready final : __at_thread_exit_elt
586 : {
587 : weak_ptr<_State_baseV2> _M_shared_state;
588 : static void _S_run(void*);
589 : void _M_set();
590 : };
591 : };
592 :
593 : #ifdef _GLIBCXX_ASYNC_ABI_COMPAT
594 : class _State_base;
595 : class _Async_state_common;
596 : #else
597 : using _State_base = _State_baseV2;
598 : class _Async_state_commonV2;
599 : #endif
600 :
601 : template<typename _BoundFn,
602 : typename _Res = decltype(std::declval<_BoundFn&>()())>
603 : class _Deferred_state;
604 :
605 : template<typename _BoundFn,
606 : typename _Res = decltype(std::declval<_BoundFn&>()())>
607 : class _Async_state_impl;
608 :
609 : template<typename _Signature>
610 : class _Task_state_base;
611 :
612 : template<typename _Fn, typename _Alloc, typename _Signature>
613 : class _Task_state;
614 :
615 : template<typename _Res_ptr, typename _Fn,
616 : typename _Res = typename _Res_ptr::element_type::result_type>
617 : struct _Task_setter;
618 :
619 : template<typename _Res_ptr, typename _BoundFn>
620 : static _Task_setter<_Res_ptr, _BoundFn>
621 : _S_task_setter(_Res_ptr& __ptr, _BoundFn& __call)
622 : {
623 : return { std::__addressof(__ptr), std::__addressof(__call) };
624 : }
625 : };
626 :
627 : /// Partial specialization for reference types.
628 : template<typename _Res>
629 : struct __future_base::_Result<_Res&> : __future_base::_Result_base
630 : {
631 : typedef _Res& result_type;
632 :
633 : _Result() noexcept : _M_value_ptr() { }
634 :
635 : void
636 : _M_set(_Res& __res) noexcept
637 : { _M_value_ptr = std::addressof(__res); }
638 :
639 : _Res& _M_get() noexcept { return *_M_value_ptr; }
640 :
641 : private:
642 : _Res* _M_value_ptr;
643 :
644 : void _M_destroy() { delete this; }
645 : };
646 :
647 : /// Explicit specialization for void.
648 : template<>
649 : struct __future_base::_Result<void> : __future_base::_Result_base
650 : {
651 : typedef void result_type;
652 :
653 : private:
654 : void _M_destroy() { delete this; }
655 : };
656 :
657 : #ifndef _GLIBCXX_ASYNC_ABI_COMPAT
658 :
659 : // Allow _Setter objects to be stored locally in std::function
660 : template<typename _Res, typename _Arg>
661 : struct __is_location_invariant
662 : <__future_base::_State_base::_Setter<_Res, _Arg>>
663 : : true_type { };
664 :
665 : // Allow _Task_setter objects to be stored locally in std::function
666 : template<typename _Res_ptr, typename _Fn, typename _Res>
667 : struct __is_location_invariant
668 : <__future_base::_Task_setter<_Res_ptr, _Fn, _Res>>
669 : : true_type { };
670 :
671 : /// Common implementation for future and shared_future.
672 : template<typename _Res>
673 : class __basic_future : public __future_base
674 : {
675 : protected:
676 : typedef shared_ptr<_State_base> __state_type;
677 : typedef __future_base::_Result<_Res>& __result_type;
678 :
679 : private:
680 : __state_type _M_state;
681 :
682 : public:
683 : // Disable copying.
684 : __basic_future(const __basic_future&) = delete;
685 : __basic_future& operator=(const __basic_future&) = delete;
686 :
687 : bool
688 303 : valid() const noexcept { return static_cast<bool>(_M_state); }
689 :
690 : void
691 1146 : wait() const
692 : {
693 1146 : _State_base::_S_check(_M_state);
694 1146 : _M_state->wait();
695 1146 : }
696 :
697 : template<typename _Rep, typename _Period>
698 : future_status
699 293 : wait_for(const chrono::duration<_Rep, _Period>& __rel) const
700 : {
701 293 : _State_base::_S_check(_M_state);
702 293 : return _M_state->wait_for(__rel);
703 : }
704 :
705 : template<typename _Clock, typename _Duration>
706 : future_status
707 : wait_until(const chrono::time_point<_Clock, _Duration>& __abs) const
708 : {
709 : _State_base::_S_check(_M_state);
710 : return _M_state->wait_until(__abs);
711 : }
712 :
713 : protected:
714 : /// Wait for the state to be ready and rethrow any stored exception
715 : __result_type
716 2904 : _M_get_result() const
717 : {
718 2904 : _State_base::_S_check(_M_state);
719 2904 : _Result_base& __res = _M_state->wait();
720 2904 : if (!(__res._M_error == nullptr))
721 0 : rethrow_exception(__res._M_error);
722 2904 : return static_cast<__result_type>(__res);
723 : }
724 :
725 1578 : void _M_swap(__basic_future& __that) noexcept
726 : {
727 1578 : _M_state.swap(__that._M_state);
728 1578 : }
729 :
730 : // Construction of a future by promise::get_future()
731 : explicit
732 2698 : __basic_future(const __state_type& __state) : _M_state(__state)
733 : {
734 2698 : _State_base::_S_check(_M_state);
735 2698 : _M_state->_M_set_retrieved_flag();
736 2698 : }
737 :
738 : // Copy construction from a shared_future
739 : explicit
740 : __basic_future(const shared_future<_Res>&) noexcept;
741 :
742 : // Move construction from a shared_future
743 : explicit
744 : __basic_future(shared_future<_Res>&&) noexcept;
745 :
746 : // Move construction from a future
747 : explicit
748 : __basic_future(future<_Res>&&) noexcept;
749 :
750 1649 : constexpr __basic_future() noexcept : _M_state() { }
751 :
752 : struct _Reset
753 : {
754 1343 : explicit _Reset(__basic_future& __fut) noexcept : _M_fut(__fut) { }
755 1343 : ~_Reset() { _M_fut._M_state.reset(); }
756 : __basic_future& _M_fut;
757 : };
758 : };
759 :
760 :
761 : /// Primary template for future.
762 : template<typename _Res>
763 : class future : public __basic_future<_Res>
764 : {
765 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
766 : // 3458. Is shared_future intended to work with arrays or function types?
767 : static_assert(!is_array<_Res>{}, "result type must not be an array");
768 : static_assert(!is_function<_Res>{}, "result type must not be a function");
769 : static_assert(is_destructible<_Res>{},
770 : "result type must be destructible");
771 :
772 : friend class promise<_Res>;
773 : template<typename> friend class packaged_task;
774 : template<typename _Fn, typename... _Args>
775 : friend future<__async_result_of<_Fn, _Args...>>
776 : async(launch, _Fn&&, _Args&&...);
777 :
778 : typedef __basic_future<_Res> _Base_type;
779 : typedef typename _Base_type::__state_type __state_type;
780 :
781 : explicit
782 2698 : future(const __state_type& __state) : _Base_type(__state) { }
783 :
784 : public:
785 668 : constexpr future() noexcept : _Base_type() { }
786 :
787 : /// Move constructor
788 692 : future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { }
789 :
790 : // Disable copying
791 : future(const future&) = delete;
792 : future& operator=(const future&) = delete;
793 :
794 663 : future& operator=(future&& __fut) noexcept
795 : {
796 663 : future(std::move(__fut))._M_swap(*this);
797 663 : return *this;
798 : }
799 :
800 : /// Retrieving the value
801 : _Res
802 1343 : get()
803 : {
804 1343 : typename _Base_type::_Reset __reset(*this);
805 2686 : return std::move(this->_M_get_result()._M_value());
806 1343 : }
807 :
808 : shared_future<_Res> share() noexcept;
809 : };
810 :
811 : /// Partial specialization for future<R&>
812 : template<typename _Res>
813 : class future<_Res&> : public __basic_future<_Res&>
814 : {
815 : friend class promise<_Res&>;
816 : template<typename> friend class packaged_task;
817 : template<typename _Fn, typename... _Args>
818 : friend future<__async_result_of<_Fn, _Args...>>
819 : async(launch, _Fn&&, _Args&&...);
820 :
821 : typedef __basic_future<_Res&> _Base_type;
822 : typedef typename _Base_type::__state_type __state_type;
823 :
824 : explicit
825 : future(const __state_type& __state) : _Base_type(__state) { }
826 :
827 : public:
828 : constexpr future() noexcept : _Base_type() { }
829 :
830 : /// Move constructor
831 : future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { }
832 :
833 : // Disable copying
834 : future(const future&) = delete;
835 : future& operator=(const future&) = delete;
836 :
837 : future& operator=(future&& __fut) noexcept
838 : {
839 : future(std::move(__fut))._M_swap(*this);
840 : return *this;
841 : }
842 :
843 : /// Retrieving the value
844 : _Res&
845 : get()
846 : {
847 : typename _Base_type::_Reset __reset(*this);
848 : return this->_M_get_result()._M_get();
849 : }
850 :
851 : shared_future<_Res&> share() noexcept;
852 : };
853 :
854 : /// Explicit specialization for future<void>
855 : template<>
856 : class future<void> : public __basic_future<void>
857 : {
858 : friend class promise<void>;
859 : template<typename> friend class packaged_task;
860 : template<typename _Fn, typename... _Args>
861 : friend future<__async_result_of<_Fn, _Args...>>
862 : async(launch, _Fn&&, _Args&&...);
863 :
864 : typedef __basic_future<void> _Base_type;
865 : typedef typename _Base_type::__state_type __state_type;
866 :
867 : explicit
868 : future(const __state_type& __state) : _Base_type(__state) { }
869 :
870 : public:
871 : constexpr future() noexcept : _Base_type() { }
872 :
873 : /// Move constructor
874 : future(future&& __uf) noexcept : _Base_type(std::move(__uf)) { }
875 :
876 : // Disable copying
877 : future(const future&) = delete;
878 : future& operator=(const future&) = delete;
879 :
880 : future& operator=(future&& __fut) noexcept
881 : {
882 : future(std::move(__fut))._M_swap(*this);
883 : return *this;
884 : }
885 :
886 : /// Retrieving the value
887 : void
888 : get()
889 : {
890 : typename _Base_type::_Reset __reset(*this);
891 : this->_M_get_result();
892 : }
893 :
894 : shared_future<void> share() noexcept;
895 : };
896 :
897 :
898 : /// Primary template for shared_future.
899 : template<typename _Res>
900 : class shared_future : public __basic_future<_Res>
901 : {
902 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
903 : // 3458. Is shared_future intended to work with arrays or function types?
904 : static_assert(!is_array<_Res>{}, "result type must not be an array");
905 : static_assert(!is_function<_Res>{}, "result type must not be a function");
906 : static_assert(is_destructible<_Res>{},
907 : "result type must be destructible");
908 :
909 : typedef __basic_future<_Res> _Base_type;
910 :
911 : public:
912 981 : constexpr shared_future() noexcept : _Base_type() { }
913 :
914 : /// Copy constructor
915 2286 : shared_future(const shared_future& __sf) noexcept : _Base_type(__sf) { }
916 :
917 : /// Construct from a future rvalue
918 918 : shared_future(future<_Res>&& __uf) noexcept
919 918 : : _Base_type(std::move(__uf))
920 918 : { }
921 :
922 : /// Construct from a shared_future rvalue
923 1555 : shared_future(shared_future&& __sf) noexcept
924 1555 : : _Base_type(std::move(__sf))
925 1555 : { }
926 :
927 634 : shared_future& operator=(const shared_future& __sf) noexcept
928 : {
929 634 : shared_future(__sf)._M_swap(*this);
930 634 : return *this;
931 : }
932 :
933 281 : shared_future& operator=(shared_future&& __sf) noexcept
934 : {
935 281 : shared_future(std::move(__sf))._M_swap(*this);
936 281 : return *this;
937 : }
938 :
939 : /// Retrieving the value
940 : const _Res&
941 1561 : get() const { return this->_M_get_result()._M_value(); }
942 : };
943 :
944 : /// Partial specialization for shared_future<R&>
945 : template<typename _Res>
946 : class shared_future<_Res&> : public __basic_future<_Res&>
947 : {
948 : typedef __basic_future<_Res&> _Base_type;
949 :
950 : public:
951 : constexpr shared_future() noexcept : _Base_type() { }
952 :
953 : /// Copy constructor
954 : shared_future(const shared_future& __sf) : _Base_type(__sf) { }
955 :
956 : /// Construct from a future rvalue
957 : shared_future(future<_Res&>&& __uf) noexcept
958 : : _Base_type(std::move(__uf))
959 : { }
960 :
961 : /// Construct from a shared_future rvalue
962 : shared_future(shared_future&& __sf) noexcept
963 : : _Base_type(std::move(__sf))
964 : { }
965 :
966 : shared_future& operator=(const shared_future& __sf)
967 : {
968 : shared_future(__sf)._M_swap(*this);
969 : return *this;
970 : }
971 :
972 : shared_future& operator=(shared_future&& __sf) noexcept
973 : {
974 : shared_future(std::move(__sf))._M_swap(*this);
975 : return *this;
976 : }
977 :
978 : /// Retrieving the value
979 : _Res&
980 : get() const { return this->_M_get_result()._M_get(); }
981 : };
982 :
983 : /// Explicit specialization for shared_future<void>
984 : template<>
985 : class shared_future<void> : public __basic_future<void>
986 : {
987 : typedef __basic_future<void> _Base_type;
988 :
989 : public:
990 : constexpr shared_future() noexcept : _Base_type() { }
991 :
992 : /// Copy constructor
993 : shared_future(const shared_future& __sf) : _Base_type(__sf) { }
994 :
995 : /// Construct from a future rvalue
996 : shared_future(future<void>&& __uf) noexcept
997 : : _Base_type(std::move(__uf))
998 : { }
999 :
1000 : /// Construct from a shared_future rvalue
1001 : shared_future(shared_future&& __sf) noexcept
1002 : : _Base_type(std::move(__sf))
1003 : { }
1004 :
1005 : shared_future& operator=(const shared_future& __sf)
1006 : {
1007 : shared_future(__sf)._M_swap(*this);
1008 : return *this;
1009 : }
1010 :
1011 : shared_future& operator=(shared_future&& __sf) noexcept
1012 : {
1013 : shared_future(std::move(__sf))._M_swap(*this);
1014 : return *this;
1015 : }
1016 :
1017 : // Retrieving the value
1018 : void
1019 : get() const { this->_M_get_result(); }
1020 : };
1021 :
1022 : // Now we can define the protected __basic_future constructors.
1023 : template<typename _Res>
1024 2286 : inline __basic_future<_Res>::
1025 : __basic_future(const shared_future<_Res>& __sf) noexcept
1026 2286 : : _M_state(__sf._M_state)
1027 2286 : { }
1028 :
1029 : template<typename _Res>
1030 1555 : inline __basic_future<_Res>::
1031 : __basic_future(shared_future<_Res>&& __sf) noexcept
1032 1555 : : _M_state(std::move(__sf._M_state))
1033 1555 : { }
1034 :
1035 : template<typename _Res>
1036 1610 : inline __basic_future<_Res>::
1037 : __basic_future(future<_Res>&& __uf) noexcept
1038 1610 : : _M_state(std::move(__uf._M_state))
1039 1610 : { }
1040 :
1041 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
1042 : // 2556. Wide contract for future::share()
1043 : template<typename _Res>
1044 : inline shared_future<_Res>
1045 214 : future<_Res>::share() noexcept
1046 214 : { return shared_future<_Res>(std::move(*this)); }
1047 :
1048 : template<typename _Res>
1049 : inline shared_future<_Res&>
1050 : future<_Res&>::share() noexcept
1051 : { return shared_future<_Res&>(std::move(*this)); }
1052 :
1053 : inline shared_future<void>
1054 : future<void>::share() noexcept
1055 : { return shared_future<void>(std::move(*this)); }
1056 :
1057 : /// Primary template for promise
1058 : template<typename _Res>
1059 : class promise
1060 : {
1061 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
1062 : // 3466: Specify the requirements for promise/future/[...] consistently
1063 : static_assert(!is_array<_Res>{}, "result type must not be an array");
1064 : static_assert(!is_function<_Res>{}, "result type must not be a function");
1065 : static_assert(is_destructible<_Res>{},
1066 : "result type must be destructible");
1067 :
1068 : typedef __future_base::_State_base _State;
1069 : typedef __future_base::_Result<_Res> _Res_type;
1070 : typedef __future_base::_Ptr<_Res_type> _Ptr_type;
1071 : template<typename, typename> friend struct _State::_Setter;
1072 : friend _State;
1073 :
1074 : shared_ptr<_State> _M_future;
1075 : _Ptr_type _M_storage;
1076 :
1077 : public:
1078 3030 : promise()
1079 3030 : : _M_future(std::make_shared<_State>()),
1080 3030 : _M_storage(new _Res_type())
1081 3030 : { }
1082 :
1083 : promise(promise&& __rhs) noexcept
1084 : : _M_future(std::move(__rhs._M_future)),
1085 : _M_storage(std::move(__rhs._M_storage))
1086 : { }
1087 :
1088 : template<typename _Allocator>
1089 : promise(allocator_arg_t, const _Allocator& __a)
1090 : : _M_future(std::allocate_shared<_State>(__a)),
1091 : _M_storage(__future_base::_S_allocate_result<_Res>(__a))
1092 : { }
1093 :
1094 : template<typename _Allocator>
1095 : promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
1096 : : _M_future(std::move(__rhs._M_future)),
1097 : _M_storage(std::move(__rhs._M_storage))
1098 : { }
1099 :
1100 : promise(const promise&) = delete;
1101 :
1102 3030 : ~promise()
1103 : {
1104 3030 : if (static_cast<bool>(_M_future) && !_M_future.unique())
1105 1267 : _M_future->_M_break_promise(std::move(_M_storage));
1106 3030 : }
1107 :
1108 : // Assignment
1109 : promise&
1110 : operator=(promise&& __rhs) noexcept
1111 : {
1112 : promise(std::move(__rhs)).swap(*this);
1113 : return *this;
1114 : }
1115 :
1116 : promise& operator=(const promise&) = delete;
1117 :
1118 : void
1119 295 : swap(promise& __rhs) noexcept
1120 : {
1121 295 : _M_future.swap(__rhs._M_future);
1122 295 : _M_storage.swap(__rhs._M_storage);
1123 295 : }
1124 :
1125 : // Retrieving the result
1126 : future<_Res>
1127 2698 : get_future()
1128 2698 : { return future<_Res>(_M_future); }
1129 :
1130 : // Setting the result
1131 : void
1132 995 : set_value(const _Res& __r)
1133 1990 : { _M_state()._M_set_result(_State::__setter(this, __r)); }
1134 :
1135 : void
1136 1703 : set_value(_Res&& __r)
1137 3406 : { _M_state()._M_set_result(_State::__setter(this, std::move(__r))); }
1138 :
1139 : void
1140 0 : set_exception(exception_ptr __p)
1141 0 : { _M_state()._M_set_result(_State::__setter(__p, this)); }
1142 :
1143 : void
1144 : set_value_at_thread_exit(const _Res& __r)
1145 : {
1146 : _M_state()._M_set_delayed_result(_State::__setter(this, __r),
1147 : _M_future);
1148 : }
1149 :
1150 : void
1151 : set_value_at_thread_exit(_Res&& __r)
1152 : {
1153 : _M_state()._M_set_delayed_result(
1154 : _State::__setter(this, std::move(__r)), _M_future);
1155 : }
1156 :
1157 : void
1158 : set_exception_at_thread_exit(exception_ptr __p)
1159 : {
1160 : _M_state()._M_set_delayed_result(_State::__setter(__p, this),
1161 : _M_future);
1162 : }
1163 :
1164 : private:
1165 : _State&
1166 2698 : _M_state()
1167 : {
1168 2698 : __future_base::_State_base::_S_check(_M_future);
1169 2698 : return *_M_future;
1170 : }
1171 : };
1172 :
1173 : template<typename _Res>
1174 : inline void
1175 : swap(promise<_Res>& __x, promise<_Res>& __y) noexcept
1176 : { __x.swap(__y); }
1177 :
1178 : template<typename _Res, typename _Alloc>
1179 : struct uses_allocator<promise<_Res>, _Alloc>
1180 : : public true_type { };
1181 :
1182 :
1183 : /// Partial specialization for promise<R&>
1184 : template<typename _Res>
1185 : class promise<_Res&>
1186 : {
1187 : typedef __future_base::_State_base _State;
1188 : typedef __future_base::_Result<_Res&> _Res_type;
1189 : typedef __future_base::_Ptr<_Res_type> _Ptr_type;
1190 : template<typename, typename> friend struct _State::_Setter;
1191 : friend _State;
1192 :
1193 : shared_ptr<_State> _M_future;
1194 : _Ptr_type _M_storage;
1195 :
1196 : public:
1197 : promise()
1198 : : _M_future(std::make_shared<_State>()),
1199 : _M_storage(new _Res_type())
1200 : { }
1201 :
1202 : promise(promise&& __rhs) noexcept
1203 : : _M_future(std::move(__rhs._M_future)),
1204 : _M_storage(std::move(__rhs._M_storage))
1205 : { }
1206 :
1207 : template<typename _Allocator>
1208 : promise(allocator_arg_t, const _Allocator& __a)
1209 : : _M_future(std::allocate_shared<_State>(__a)),
1210 : _M_storage(__future_base::_S_allocate_result<_Res&>(__a))
1211 : { }
1212 :
1213 : template<typename _Allocator>
1214 : promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
1215 : : _M_future(std::move(__rhs._M_future)),
1216 : _M_storage(std::move(__rhs._M_storage))
1217 : { }
1218 :
1219 : promise(const promise&) = delete;
1220 :
1221 : ~promise()
1222 : {
1223 : if (static_cast<bool>(_M_future) && !_M_future.unique())
1224 : _M_future->_M_break_promise(std::move(_M_storage));
1225 : }
1226 :
1227 : // Assignment
1228 : promise&
1229 : operator=(promise&& __rhs) noexcept
1230 : {
1231 : promise(std::move(__rhs)).swap(*this);
1232 : return *this;
1233 : }
1234 :
1235 : promise& operator=(const promise&) = delete;
1236 :
1237 : void
1238 : swap(promise& __rhs) noexcept
1239 : {
1240 : _M_future.swap(__rhs._M_future);
1241 : _M_storage.swap(__rhs._M_storage);
1242 : }
1243 :
1244 : // Retrieving the result
1245 : future<_Res&>
1246 : get_future()
1247 : { return future<_Res&>(_M_future); }
1248 :
1249 : // Setting the result
1250 : void
1251 : set_value(_Res& __r)
1252 : { _M_state()._M_set_result(_State::__setter(this, __r)); }
1253 :
1254 : void
1255 : set_exception(exception_ptr __p)
1256 : { _M_state()._M_set_result(_State::__setter(__p, this)); }
1257 :
1258 : void
1259 : set_value_at_thread_exit(_Res& __r)
1260 : {
1261 : _M_state()._M_set_delayed_result(_State::__setter(this, __r),
1262 : _M_future);
1263 : }
1264 :
1265 : void
1266 : set_exception_at_thread_exit(exception_ptr __p)
1267 : {
1268 : _M_state()._M_set_delayed_result(_State::__setter(__p, this),
1269 : _M_future);
1270 : }
1271 :
1272 : private:
1273 : _State&
1274 : _M_state()
1275 : {
1276 : __future_base::_State_base::_S_check(_M_future);
1277 : return *_M_future;
1278 : }
1279 : };
1280 :
1281 : /// Explicit specialization for promise<void>
1282 : template<>
1283 : class promise<void>
1284 : {
1285 : typedef __future_base::_State_base _State;
1286 : typedef __future_base::_Result<void> _Res_type;
1287 : typedef __future_base::_Ptr<_Res_type> _Ptr_type;
1288 : template<typename, typename> friend struct _State::_Setter;
1289 : friend _State;
1290 :
1291 : shared_ptr<_State> _M_future;
1292 : _Ptr_type _M_storage;
1293 :
1294 : public:
1295 : promise()
1296 : : _M_future(std::make_shared<_State>()),
1297 : _M_storage(new _Res_type())
1298 : { }
1299 :
1300 : promise(promise&& __rhs) noexcept
1301 : : _M_future(std::move(__rhs._M_future)),
1302 : _M_storage(std::move(__rhs._M_storage))
1303 : { }
1304 :
1305 : template<typename _Allocator>
1306 : promise(allocator_arg_t, const _Allocator& __a)
1307 : : _M_future(std::allocate_shared<_State>(__a)),
1308 : _M_storage(__future_base::_S_allocate_result<void>(__a))
1309 : { }
1310 :
1311 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
1312 : // 2095. missing constructors needed for uses-allocator construction
1313 : template<typename _Allocator>
1314 : promise(allocator_arg_t, const _Allocator&, promise&& __rhs)
1315 : : _M_future(std::move(__rhs._M_future)),
1316 : _M_storage(std::move(__rhs._M_storage))
1317 : { }
1318 :
1319 : promise(const promise&) = delete;
1320 :
1321 : ~promise()
1322 : {
1323 : if (static_cast<bool>(_M_future) && !_M_future.unique())
1324 : _M_future->_M_break_promise(std::move(_M_storage));
1325 : }
1326 :
1327 : // Assignment
1328 : promise&
1329 : operator=(promise&& __rhs) noexcept
1330 : {
1331 : promise(std::move(__rhs)).swap(*this);
1332 : return *this;
1333 : }
1334 :
1335 : promise& operator=(const promise&) = delete;
1336 :
1337 : void
1338 : swap(promise& __rhs) noexcept
1339 : {
1340 : _M_future.swap(__rhs._M_future);
1341 : _M_storage.swap(__rhs._M_storage);
1342 : }
1343 :
1344 : // Retrieving the result
1345 : future<void>
1346 : get_future()
1347 : { return future<void>(_M_future); }
1348 :
1349 : // Setting the result
1350 : void
1351 : set_value()
1352 : { _M_state()._M_set_result(_State::__setter(this)); }
1353 :
1354 : void
1355 : set_exception(exception_ptr __p)
1356 : { _M_state()._M_set_result(_State::__setter(__p, this)); }
1357 :
1358 : void
1359 : set_value_at_thread_exit()
1360 : { _M_state()._M_set_delayed_result(_State::__setter(this), _M_future); }
1361 :
1362 : void
1363 : set_exception_at_thread_exit(exception_ptr __p)
1364 : {
1365 : _M_state()._M_set_delayed_result(_State::__setter(__p, this),
1366 : _M_future);
1367 : }
1368 :
1369 : private:
1370 : _State&
1371 : _M_state()
1372 : {
1373 : __future_base::_State_base::_S_check(_M_future);
1374 : return *_M_future;
1375 : }
1376 : };
1377 :
1378 : template<typename _Ptr_type, typename _Fn, typename _Res>
1379 : struct __future_base::_Task_setter
1380 : {
1381 : // Invoke the function and provide the result to the caller.
1382 : _Ptr_type operator()() const
1383 : {
1384 : __try
1385 : {
1386 : (*_M_result)->_M_set((*_M_fn)());
1387 : }
1388 : __catch(const __cxxabiv1::__forced_unwind&)
1389 : {
1390 : __throw_exception_again; // will cause broken_promise
1391 : }
1392 : __catch(...)
1393 : {
1394 : (*_M_result)->_M_error = current_exception();
1395 : }
1396 : return std::move(*_M_result);
1397 : }
1398 : _Ptr_type* _M_result;
1399 : _Fn* _M_fn;
1400 : };
1401 :
1402 : template<typename _Ptr_type, typename _Fn>
1403 : struct __future_base::_Task_setter<_Ptr_type, _Fn, void>
1404 : {
1405 : _Ptr_type operator()() const
1406 : {
1407 : __try
1408 : {
1409 : (*_M_fn)();
1410 : }
1411 : __catch(const __cxxabiv1::__forced_unwind&)
1412 : {
1413 : __throw_exception_again; // will cause broken_promise
1414 : }
1415 : __catch(...)
1416 : {
1417 : (*_M_result)->_M_error = current_exception();
1418 : }
1419 : return std::move(*_M_result);
1420 : }
1421 : _Ptr_type* _M_result;
1422 : _Fn* _M_fn;
1423 : };
1424 :
1425 : // Holds storage for a packaged_task's result.
1426 : template<typename _Res, typename... _Args>
1427 : struct __future_base::_Task_state_base<_Res(_Args...)>
1428 : : __future_base::_State_base
1429 : {
1430 : typedef _Res _Res_type;
1431 :
1432 : template<typename _Alloc>
1433 : _Task_state_base(const _Alloc& __a)
1434 : : _M_result(_S_allocate_result<_Res>(__a))
1435 : { }
1436 :
1437 : // Invoke the stored task and make the state ready.
1438 : virtual void
1439 : _M_run(_Args&&... __args) = 0;
1440 :
1441 : // Invoke the stored task and make the state ready at thread exit.
1442 : virtual void
1443 : _M_run_delayed(_Args&&... __args, weak_ptr<_State_base>) = 0;
1444 :
1445 : virtual shared_ptr<_Task_state_base>
1446 : _M_reset() = 0;
1447 :
1448 : typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type;
1449 : _Ptr_type _M_result;
1450 : };
1451 :
1452 : // Holds a packaged_task's stored task.
1453 : template<typename _Fn, typename _Alloc, typename _Res, typename... _Args>
1454 : struct __future_base::_Task_state<_Fn, _Alloc, _Res(_Args...)> final
1455 : : __future_base::_Task_state_base<_Res(_Args...)>
1456 : {
1457 : template<typename _Fn2>
1458 : _Task_state(_Fn2&& __fn, const _Alloc& __a)
1459 : : _Task_state_base<_Res(_Args...)>(__a),
1460 : _M_impl(std::forward<_Fn2>(__fn), __a)
1461 : { }
1462 :
1463 : private:
1464 : virtual void
1465 : _M_run(_Args&&... __args)
1466 : {
1467 : auto __boundfn = [&] () -> _Res {
1468 : return std::__invoke_r<_Res>(_M_impl._M_fn,
1469 : std::forward<_Args>(__args)...);
1470 : };
1471 : this->_M_set_result(_S_task_setter(this->_M_result, __boundfn));
1472 : }
1473 :
1474 : virtual void
1475 : _M_run_delayed(_Args&&... __args, weak_ptr<_State_base> __self)
1476 : {
1477 : auto __boundfn = [&] () -> _Res {
1478 : return std::__invoke_r<_Res>(_M_impl._M_fn,
1479 : std::forward<_Args>(__args)...);
1480 : };
1481 : this->_M_set_delayed_result(_S_task_setter(this->_M_result, __boundfn),
1482 : std::move(__self));
1483 : }
1484 :
1485 : virtual shared_ptr<_Task_state_base<_Res(_Args...)>>
1486 : _M_reset();
1487 :
1488 : struct _Impl : _Alloc
1489 : {
1490 : template<typename _Fn2>
1491 : _Impl(_Fn2&& __fn, const _Alloc& __a)
1492 : : _Alloc(__a), _M_fn(std::forward<_Fn2>(__fn)) { }
1493 : _Fn _M_fn;
1494 : } _M_impl;
1495 : };
1496 :
1497 : template<typename _Signature, typename _Fn,
1498 : typename _Alloc = std::allocator<int>>
1499 : static shared_ptr<__future_base::_Task_state_base<_Signature>>
1500 : __create_task_state(_Fn&& __fn, const _Alloc& __a = _Alloc())
1501 : {
1502 : typedef typename decay<_Fn>::type _Fn2;
1503 : typedef __future_base::_Task_state<_Fn2, _Alloc, _Signature> _State;
1504 : return std::allocate_shared<_State>(__a, std::forward<_Fn>(__fn), __a);
1505 : }
1506 :
1507 : template<typename _Fn, typename _Alloc, typename _Res, typename... _Args>
1508 : shared_ptr<__future_base::_Task_state_base<_Res(_Args...)>>
1509 : __future_base::_Task_state<_Fn, _Alloc, _Res(_Args...)>::_M_reset()
1510 : {
1511 : return __create_task_state<_Res(_Args...)>(std::move(_M_impl._M_fn),
1512 : static_cast<_Alloc&>(_M_impl));
1513 : }
1514 :
1515 : /// packaged_task
1516 : template<typename _Res, typename... _ArgTypes>
1517 : class packaged_task<_Res(_ArgTypes...)>
1518 : {
1519 : typedef __future_base::_Task_state_base<_Res(_ArgTypes...)> _State_type;
1520 : shared_ptr<_State_type> _M_state;
1521 :
1522 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
1523 : // 3039. Unnecessary decay in thread and packaged_task
1524 : template<typename _Fn, typename _Fn2 = __remove_cvref_t<_Fn>>
1525 : using __not_same
1526 : = typename enable_if<!is_same<packaged_task, _Fn2>::value>::type;
1527 :
1528 : public:
1529 : // Construction and destruction
1530 : packaged_task() noexcept { }
1531 :
1532 : template<typename _Fn, typename = __not_same<_Fn>>
1533 : explicit
1534 : packaged_task(_Fn&& __fn)
1535 : : _M_state(
1536 : __create_task_state<_Res(_ArgTypes...)>(std::forward<_Fn>(__fn)))
1537 : { }
1538 :
1539 : #if __cplusplus < 201703L
1540 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
1541 : // 2097. packaged_task constructors should be constrained
1542 : // 2407. [this constructor should not be] explicit
1543 : // 2921. packaged_task and type-erased allocators
1544 : template<typename _Fn, typename _Alloc, typename = __not_same<_Fn>>
1545 : packaged_task(allocator_arg_t, const _Alloc& __a, _Fn&& __fn)
1546 : : _M_state(__create_task_state<_Res(_ArgTypes...)>(
1547 : std::forward<_Fn>(__fn), __a))
1548 : { }
1549 :
1550 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
1551 : // 2095. missing constructors needed for uses-allocator construction
1552 : template<typename _Allocator>
1553 : packaged_task(allocator_arg_t, const _Allocator& __a) noexcept
1554 : { }
1555 :
1556 : template<typename _Allocator>
1557 : packaged_task(allocator_arg_t, const _Allocator&,
1558 : const packaged_task&) = delete;
1559 :
1560 : template<typename _Allocator>
1561 : packaged_task(allocator_arg_t, const _Allocator&,
1562 : packaged_task&& __other) noexcept
1563 : { this->swap(__other); }
1564 : #endif
1565 :
1566 : ~packaged_task()
1567 : {
1568 : if (static_cast<bool>(_M_state) && !_M_state.unique())
1569 : _M_state->_M_break_promise(std::move(_M_state->_M_result));
1570 : }
1571 :
1572 : // No copy
1573 : packaged_task(const packaged_task&) = delete;
1574 : packaged_task& operator=(const packaged_task&) = delete;
1575 :
1576 : // Move support
1577 : packaged_task(packaged_task&& __other) noexcept
1578 : { this->swap(__other); }
1579 :
1580 : packaged_task& operator=(packaged_task&& __other) noexcept
1581 : {
1582 : packaged_task(std::move(__other)).swap(*this);
1583 : return *this;
1584 : }
1585 :
1586 : void
1587 : swap(packaged_task& __other) noexcept
1588 : { _M_state.swap(__other._M_state); }
1589 :
1590 : bool
1591 : valid() const noexcept
1592 : { return static_cast<bool>(_M_state); }
1593 :
1594 : // Result retrieval
1595 : future<_Res>
1596 : get_future()
1597 : { return future<_Res>(_M_state); }
1598 :
1599 : // Execution
1600 : void
1601 : operator()(_ArgTypes... __args)
1602 : {
1603 : __future_base::_State_base::_S_check(_M_state);
1604 : _M_state->_M_run(std::forward<_ArgTypes>(__args)...);
1605 : }
1606 :
1607 : void
1608 : make_ready_at_thread_exit(_ArgTypes... __args)
1609 : {
1610 : __future_base::_State_base::_S_check(_M_state);
1611 : _M_state->_M_run_delayed(std::forward<_ArgTypes>(__args)..., _M_state);
1612 : }
1613 :
1614 : void
1615 : reset()
1616 : {
1617 : __future_base::_State_base::_S_check(_M_state);
1618 : packaged_task __tmp;
1619 : __tmp._M_state = _M_state;
1620 : _M_state = _M_state->_M_reset();
1621 : }
1622 : };
1623 :
1624 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
1625 : // 3117. Missing packaged_task deduction guides
1626 : #if __cpp_deduction_guides >= 201606
1627 : template<typename _Res, typename... _ArgTypes>
1628 : packaged_task(_Res(*)(_ArgTypes...)) -> packaged_task<_Res(_ArgTypes...)>;
1629 :
1630 : template<typename _Fun, typename _Signature = typename
1631 : __function_guide_helper<decltype(&_Fun::operator())>::type>
1632 : packaged_task(_Fun) -> packaged_task<_Signature>;
1633 : #endif
1634 :
1635 : /// swap
1636 : template<typename _Res, typename... _ArgTypes>
1637 : inline void
1638 : swap(packaged_task<_Res(_ArgTypes...)>& __x,
1639 : packaged_task<_Res(_ArgTypes...)>& __y) noexcept
1640 : { __x.swap(__y); }
1641 :
1642 : #if __cplusplus < 201703L
1643 : // _GLIBCXX_RESOLVE_LIB_DEFECTS
1644 : // 2976. Dangling uses_allocator specialization for packaged_task
1645 : template<typename _Res, typename _Alloc>
1646 : struct uses_allocator<packaged_task<_Res>, _Alloc>
1647 : : public true_type { };
1648 : #endif
1649 :
1650 : // Shared state created by std::async().
1651 : // Holds a deferred function and storage for its result.
1652 : template<typename _BoundFn, typename _Res>
1653 : class __future_base::_Deferred_state final
1654 : : public __future_base::_State_base
1655 : {
1656 : public:
1657 : template<typename... _Args>
1658 : explicit
1659 : _Deferred_state(_Args&&... __args)
1660 : : _M_result(new _Result<_Res>()),
1661 : _M_fn(std::forward<_Args>(__args)...)
1662 : { }
1663 :
1664 : private:
1665 : typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type;
1666 : _Ptr_type _M_result;
1667 : _BoundFn _M_fn;
1668 :
1669 : // Run the deferred function.
1670 : virtual void
1671 : _M_complete_async()
1672 : {
1673 : // Multiple threads can call a waiting function on the future and
1674 : // reach this point at the same time. The call_once in _M_set_result
1675 : // ensures only the first one run the deferred function, stores the
1676 : // result in _M_result, swaps that with the base _M_result and makes
1677 : // the state ready. Tell _M_set_result to ignore failure so all later
1678 : // calls do nothing.
1679 : _M_set_result(_S_task_setter(_M_result, _M_fn), true);
1680 : }
1681 :
1682 : // Caller should check whether the state is ready first, because this
1683 : // function will return true even after the deferred function has run.
1684 : virtual bool _M_is_deferred_future() const { return true; }
1685 : };
1686 :
1687 : // Common functionality hoisted out of the _Async_state_impl template.
1688 : class __future_base::_Async_state_commonV2
1689 : : public __future_base::_State_base
1690 : {
1691 : protected:
1692 : ~_Async_state_commonV2() = default;
1693 :
1694 : // Make waiting functions block until the thread completes, as if joined.
1695 : //
1696 : // This function is used by wait() to satisfy the first requirement below
1697 : // and by wait_for() / wait_until() to satisfy the second.
1698 : //
1699 : // [futures.async]:
1700 : //
1701 : // - a call to a waiting function on an asynchronous return object that
1702 : // shares the shared state created by this async call shall block until
1703 : // the associated thread has completed, as if joined, or else time out.
1704 : //
1705 : // - the associated thread completion synchronizes with the return from
1706 : // the first function that successfully detects the ready status of the
1707 : // shared state or with the return from the last function that releases
1708 : // the shared state, whichever happens first.
1709 : virtual void _M_complete_async() { _M_join(); }
1710 :
1711 : void _M_join() { std::call_once(_M_once, &thread::join, &_M_thread); }
1712 :
1713 : thread _M_thread;
1714 : once_flag _M_once;
1715 : };
1716 :
1717 : // Shared state created by std::async().
1718 : // Starts a new thread that runs a function and makes the shared state ready.
1719 : template<typename _BoundFn, typename _Res>
1720 : class __future_base::_Async_state_impl final
1721 : : public __future_base::_Async_state_commonV2
1722 : {
1723 : public:
1724 : template<typename... _Args>
1725 : explicit
1726 : _Async_state_impl(_Args&&... __args)
1727 : : _M_result(new _Result<_Res>()),
1728 : _M_fn(std::forward<_Args>(__args)...)
1729 : {
1730 : _M_thread = std::thread{&_Async_state_impl::_M_run, this};
1731 : }
1732 :
1733 : // Must not destroy _M_result and _M_fn until the thread finishes.
1734 : // Call join() directly rather than through _M_join() because no other
1735 : // thread can be referring to this state if it is being destroyed.
1736 : ~_Async_state_impl()
1737 : {
1738 : if (_M_thread.joinable())
1739 : _M_thread.join();
1740 : }
1741 :
1742 : private:
1743 : void
1744 : _M_run()
1745 : {
1746 : __try
1747 : {
1748 : _M_set_result(_S_task_setter(_M_result, _M_fn));
1749 : }
1750 : __catch (const __cxxabiv1::__forced_unwind&)
1751 : {
1752 : // make the shared state ready on thread cancellation
1753 : if (static_cast<bool>(_M_result))
1754 : this->_M_break_promise(std::move(_M_result));
1755 : __throw_exception_again;
1756 : }
1757 : }
1758 :
1759 : typedef __future_base::_Ptr<_Result<_Res>> _Ptr_type;
1760 : _Ptr_type _M_result;
1761 : _BoundFn _M_fn;
1762 : };
1763 :
1764 :
1765 : /// async
1766 : template<typename _Fn, typename... _Args>
1767 : _GLIBCXX_NODISCARD future<__async_result_of<_Fn, _Args...>>
1768 : async(launch __policy, _Fn&& __fn, _Args&&... __args)
1769 : {
1770 : using _Wr = std::thread::_Call_wrapper<_Fn, _Args...>;
1771 : using _As = __future_base::_Async_state_impl<_Wr>;
1772 : using _Ds = __future_base::_Deferred_state<_Wr>;
1773 :
1774 : std::shared_ptr<__future_base::_State_base> __state;
1775 : if ((__policy & launch::async) == launch::async)
1776 : {
1777 : __try
1778 : {
1779 : __state = std::make_shared<_As>(std::forward<_Fn>(__fn),
1780 : std::forward<_Args>(__args)...);
1781 : }
1782 : #if __cpp_exceptions
1783 : catch(const system_error& __e)
1784 : {
1785 : if (__e.code() != errc::resource_unavailable_try_again
1786 : || (__policy & launch::deferred) != launch::deferred)
1787 : throw;
1788 : }
1789 : #endif
1790 : }
1791 : if (!__state)
1792 : {
1793 : __state = std::make_shared<_Ds>(std::forward<_Fn>(__fn),
1794 : std::forward<_Args>(__args)...);
1795 : }
1796 : return future<__async_result_of<_Fn, _Args...>>(std::move(__state));
1797 : }
1798 :
1799 : /// async, potential overload
1800 : template<typename _Fn, typename... _Args>
1801 : _GLIBCXX_NODISCARD inline future<__async_result_of<_Fn, _Args...>>
1802 : async(_Fn&& __fn, _Args&&... __args)
1803 : {
1804 : return std::async(launch::async|launch::deferred,
1805 : std::forward<_Fn>(__fn),
1806 : std::forward<_Args>(__args)...);
1807 : }
1808 :
1809 : #endif // _GLIBCXX_ASYNC_ABI_COMPAT
1810 : #endif // _GLIBCXX_HAS_GTHREADS
1811 :
1812 : /// @} group futures
1813 : _GLIBCXX_END_NAMESPACE_VERSION
1814 : } // namespace
1815 :
1816 : #endif // C++11
1817 :
1818 : #endif // _GLIBCXX_FUTURE
|