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