Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

std::async in future does not throw system_error as required (libc++) #125428

Closed
slotosch opened this issue Feb 2, 2025 · 1 comment · Fixed by #125433
Closed

std::async in future does not throw system_error as required (libc++) #125428

slotosch opened this issue Feb 2, 2025 · 1 comment · Fixed by #125433
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. threading issues related to threading

Comments

@slotosch
Copy link

slotosch commented Feb 2, 2025

During the qualification of the C++ STL for safety we run into a corner case, which seam to be a clear, safety relevant bug (violation of requriements) and error handling is very safety critical. We found it in C++14, but it is also present in current version.
The C++14 requirement in 30.6.8 states for
Functions std::async
template <class F, class... Args>
future<result_of_t<decay_t(decay_t...)>> async(F&& f, Args&&... args);

template <class F, class... Args>
future<result_of_t<decay_t(decay_t...)>> async(launch policy, F&& f, Args&&... args);
Requirement 30.6.8-6,7

6 Throws: system_error if policy == launch::async and the implementation is unable to start a new thread.

7 Error conditions:
resource_unavailable_try_again — if policy == launch::async and the system is unable to start a new thread.

Steps to reproduce:

Set limit of threads using 
Linux, MacOS: setrlimit(RLIMIT_NPROC, lim)
QNX: setrlimit(RLIMIT_NTHR, lim)

Note 1: Use RLIMIT_NTHR for the number of threads per process on QNX. Linux and MacOS (pthread) does not support RLIMIT_NTHR and control the total number of Linux threads/processes with RLIMIT_NPROC. QNX has different threading model.

Note 2. Use reasonable limit numbers. Request the current limits first and do not exceed the current rlim_cur value.
Call async function with std::launch::async policy multiple times, more then rlim_cur value.

Expected behavior:

The function throws std::system_error exception which application may catch.

Actual behavior:

Application hangs.

Issue analysis:
In gcc (linux) the exception message is reported correctly.

Also a related bug report is found in another project. However it seems not reported to the LLVM development.
emscripten-core/emscripten#8988

Workaround (big pain!):
Control the number of active threads created with async call and do not exceed the limits.

** Example to reproduce (using attached async_ex.txt)
async_ex.txt

See the difference in GNU libstdc++ and LLVM libc++ using Linux:
clang++ -stdlib=libc++ -o async_ex async_ex.txt
./async_ex
This hangs

clang++ -stdlib=libstdc++ -o async_ex async_ex.txt
./async_ex
Output:
Expected exception: Resource temporarily unavailable

@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Feb 2, 2025
@philnik777 philnik777 added the threading issues related to threading label Feb 2, 2025
philnik777 added a commit that referenced this issue Feb 25, 2025

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
…ync (#125433)

If the creation of a thread fails, this causes an idle loop that will
never end because the thread wasn't started in the first place.

Fixes #125428
@slotosch
Copy link
Author

Thank you very much for fixing this issue so fast

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. threading issues related to threading
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants