Description
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