Skip to content

Commit b20ce83

Browse files
committed
[libc++] Don't try to wait on a thread that hasn't started in std::async
1 parent 4c4fc46 commit b20ce83

File tree

2 files changed

+61
-2
lines changed

2 files changed

+61
-2
lines changed

libcxx/include/future

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,8 @@ void __async_assoc_state<_Rp, _Fp>::__execute() {
865865

866866
template <class _Rp, class _Fp>
867867
void __async_assoc_state<_Rp, _Fp>::__on_zero_shared() _NOEXCEPT {
868-
this->wait();
868+
if (base::__state_ & base::__constructed)
869+
this->wait();
869870
base::__on_zero_shared();
870871
}
871872

@@ -902,7 +903,8 @@ void __async_assoc_state<void, _Fp>::__execute() {
902903

903904
template <class _Fp>
904905
void __async_assoc_state<void, _Fp>::__on_zero_shared() _NOEXCEPT {
905-
this->wait();
906+
if (base::__state_ & base::__constructed)
907+
this->wait();
906908
base::__on_zero_shared();
907909
}
908910

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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, no-exceptions
10+
11+
// UNSUPPORTED: c++03
12+
13+
// There is no way to limit the number of threads on windows
14+
// UNSUPPORTED: windows
15+
16+
// AIX and macOS seem to limit the number of processes, not threads via RLIMIT_NPROC
17+
// XFAIL: target={{.+}}-aix{{.*}}
18+
// XFAIL: target={{.+}}-apple-macos{{.*}}
19+
20+
// This test makes sure that we fail gracefully in care the thread creation fails. This is only reliably possible on
21+
// systems that allow limiting the number of threads that can be created. See https://llvm.org/PR125428 for more details
22+
23+
#include <cassert>
24+
#include <future>
25+
#include <system_error>
26+
27+
#if __has_include(<sys/resource.h>)
28+
# include <sys/resource.h>
29+
# ifdef RLIMIT_NPROC
30+
void force_thread_creation_failure() {
31+
rlimit lim = {1, 1};
32+
assert(setrlimit(RLIMIT_NPROC, &lim) == 0);
33+
}
34+
# else
35+
# error "No known way to force only one thread being available"
36+
# endif
37+
#else
38+
# error "No known way to force only one thread being available"
39+
#endif
40+
41+
int main(int, char**) {
42+
force_thread_creation_failure();
43+
44+
try {
45+
std::future<int> fut = std::async(std::launch::async, [] { return 1; });
46+
assert(false);
47+
} catch (const std::system_error&) {
48+
}
49+
50+
try {
51+
std::future<void> fut = std::async(std::launch::async, [] { return; });
52+
assert(false);
53+
} catch (const std::system_error&) {
54+
}
55+
56+
return 0;
57+
}

0 commit comments

Comments
 (0)