-
Notifications
You must be signed in to change notification settings - Fork 15.1k
Open
Labels
libc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Description
wait_for()
and wait_until()
for std::condition_variable
and std::condition_variable_any
take their wait duration or timeout parameters by const-reference. This can lead to unexpected behavior if the referent changes while the wait_for()
or wait_until()
blocks.
For example:
template <class _Clock, class _Duration>
_LIBCPP_HIDE_FROM_ABI cv_status
wait_until(unique_lock<mutex>& __lk, const chrono::time_point<_Clock, _Duration>& __t) {
using namespace chrono;
using __clock_tp_ns = time_point<_Clock, nanoseconds>;
typename _Clock::time_point __now = _Clock::now();
if (__t <= __now)
return cv_status::timeout;
__clock_tp_ns __t_ns = __clock_tp_ns(std::__safe_nanosecond_cast(__t.time_since_epoch()));
__do_timed_wait(__lk, __t_ns);
return _Clock::now() < __t ? cv_status::no_timeout : cv_status::timeout;
}
The duration parameter __t
is accessed by-reference, and so its value may be different before and after the wait.
For std::condition_variable_any
, this is an actual data race if the timeout parameter is protected by the lock, as the implementation accesses the timeout outside of the lock.
Metadata
Metadata
Assignees
Labels
libc++libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.