File tree Expand file tree Collapse file tree 2 files changed +42
-5
lines changed
test/std/thread/futures/futures.async Expand file tree Collapse file tree 2 files changed +42
-5
lines changed Original file line number Diff line number Diff line change @@ -865,8 +865,7 @@ void __async_assoc_state<_Rp, _Fp>::__execute() {
865865
866866template <class _Rp , class _Fp >
867867void __async_assoc_state<_Rp, _Fp>::__on_zero_shared () _NOEXCEPT {
868- if (base::__state_ & base::__constructed)
869- this ->wait ();
868+ this ->wait ();
870869 base::__on_zero_shared ();
871870}
872871
@@ -903,8 +902,7 @@ void __async_assoc_state<void, _Fp>::__execute() {
903902
904903template <class _Fp >
905904void __async_assoc_state<void , _Fp>::__on_zero_shared () _NOEXCEPT {
906- if (base::__state_ & base::__constructed)
907- this ->wait ();
905+ this ->wait ();
908906 base::__on_zero_shared ();
909907}
910908
@@ -1831,7 +1829,12 @@ template <class _Rp, class _Fp>
18311829_LIBCPP_HIDE_FROM_ABI future<_Rp> __make_async_assoc_state (_Fp&& __f) {
18321830 unique_ptr<__async_assoc_state<_Rp, _Fp>, __release_shared_count> __h (
18331831 new __async_assoc_state<_Rp, _Fp>(std::forward<_Fp>(__f)));
1834- std::thread (&__async_assoc_state<_Rp, _Fp>::__execute, __h.get ()).detach ();
1832+ try {
1833+ std::thread (&__async_assoc_state<_Rp, _Fp>::__execute, __h.get ()).detach ();
1834+ } catch (...) {
1835+ __h->__make_ready ();
1836+ throw ;
1837+ }
18351838 return future<_Rp>(__h.get ());
18361839}
18371840
Original file line number Diff line number Diff line change 1+ // ===----------------------------------------------------------------------===//
2+ //
3+ // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+ // See https://llvm.org/LICENSE.txt for license information.
5+ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+ //
7+ // ===----------------------------------------------------------------------===//
8+ //
9+ // UNSUPPORTED: no-threads
10+ // UNSUPPORTED: c++03
11+
12+ // Make sure that the `future` destructor keeps the data alive until the thread finished. This test fails by triggering
13+ // TSan. It may not be observable by normal means.
14+
15+ #include < atomic>
16+ #include < future>
17+ #include < mutex>
18+
19+ std::mutex mux;
20+
21+ int main () {
22+ using namespace std ::chrono_literals;
23+ mux.lock ();
24+ std::atomic<bool > in_async = false ;
25+ auto v = std::async (std::launch::async, [&in_async, value = 1 ]() mutable {
26+ in_async = true ;
27+ in_async.notify_all ();
28+ std::scoped_lock thread_lock (mux);
29+ value = 4 ;
30+ (void )value;
31+ });
32+ in_async.wait (true );
33+ mux.unlock ();
34+ }
You can’t perform that action at this time.
0 commit comments