diff options
author | Thomas Rodgers <trodgers@redhat.com> | 2019-11-15 03:09:19 +0000 |
---|---|---|
committer | Thomas Rodgers <rodgertq@gcc.gnu.org> | 2019-11-15 03:09:19 +0000 |
commit | 942c4b32b0553378f843e606bb56c417acbdc4be (patch) | |
tree | 41fec04827f82dc4850fc993c2d0958d8a12fb02 /libstdc++-v3/include/std/condition_variable | |
parent | f8aea5e37d12e09fef68b854a190f71d6b39e11f (diff) | |
download | gcc-942c4b32b0553378f843e606bb56c417acbdc4be.tar.gz |
Support for jthread and stop_token
* include/Makefile.am: Add <stop_token> header.
* include/Makefile.in: Regenerate.
* include/std/condition_variable: Add overloads for stop_token support
to condition_variable_any.
* include/std/stop_token: New file.
* include/std/thread: Add jthread type.
* include/std/version (__cpp_lib_jthread): New value.
* testsuite/30_threads/condition_variable_any/stop_token/1.cc: New test.
* testsuite/30_threads/condition_variable_any/stop_token/2.cc: New test.
* testsuite/30_threads/condition_variable_any/stop_token/wait_on.cc: New test.
* testsuite/30_threads/jthread/1.cc: New test.
* testsuite/30_threads/jthread/2.cc: New test.
* testsuite/30_threads/jthread/jthread.cc: New test.
* testsuite/30_threads/stop_token/1.cc: New test.
* testsuite/30_threads/stop_token/2.cc: New test.
* testsuite/30_threads/stop_token/stop_token.cc: New test.
From-SVN: r278274
Diffstat (limited to 'libstdc++-v3/include/std/condition_variable')
-rw-r--r-- | libstdc++-v3/include/std/condition_variable | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/libstdc++-v3/include/std/condition_variable b/libstdc++-v3/include/std/condition_variable index cc96661e94c..8887cee29fa 100644 --- a/libstdc++-v3/include/std/condition_variable +++ b/libstdc++-v3/include/std/condition_variable @@ -36,6 +36,7 @@ #else #include <chrono> + #include <bits/std_mutex.h> #include <bits/unique_lock.h> #include <ext/concurrence.h> @@ -45,6 +46,11 @@ #include <bits/shared_ptr.h> #include <bits/cxxabi_forced.h> +#if __cplusplus > 201703L +#define __cpp_lib_jthread 201907L +#include <stop_token> +#endif + #if defined(_GLIBCXX_HAS_GTHREADS) namespace std _GLIBCXX_VISIBILITY(default) @@ -360,6 +366,84 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION wait_for(_Lock& __lock, const chrono::duration<_Rep, _Period>& __rtime, _Predicate __p) { return wait_until(__lock, __clock_t::now() + __rtime, std::move(__p)); } + +#ifdef __cpp_lib_jthread + template <class _Lock, class _Predicate> + bool wait_on(_Lock& __lock, + stop_token __stoken, + _Predicate __p) + { + if (__stoken.stop_requested()) + { + return __p(); + } + + std::stop_callback __cb(__stoken, [this] { notify_all(); }); + shared_ptr<mutex> __mutex = _M_mutex; + while (!__p()) + { + unique_lock<mutex> __my_lock(*__mutex); + if (__stoken.stop_requested()) + { + return false; + } + // *__mutex must be unlocked before re-locking __lock so move + // ownership of *__mutex lock to an object with shorter lifetime. + _Unlock<_Lock> __unlock(__lock); + unique_lock<mutex> __my_lock2(std::move(__my_lock)); + _M_cond.wait(__my_lock2); + } + return true; + } + + template <class _Lock, class _Clock, class _Duration, class _Predicate> + bool wait_on_until(_Lock& __lock, + stop_token __stoken, + const chrono::time_point<_Clock, _Duration>& __abs_time, + _Predicate __p) + { + if (__stoken.stop_requested()) + { + return __p(); + } + + std::stop_callback __cb(__stoken, [this] { notify_all(); }); + shared_ptr<mutex> __mutex = _M_mutex; + while (!__p()) + { + bool __stop; + { + unique_lock<mutex> __my_lock(*__mutex); + if (__stoken.stop_requested()) + { + return false; + } + _Unlock<_Lock> __u(__lock); + unique_lock<mutex> __my_lock2(std::move(__my_lock)); + const auto __status = _M_cond.wait_until(__my_lock2, __abs_time); + __stop = (__status == std::cv_status::timeout) || __stoken.stop_requested(); + } + if (__stop) + { + return __p(); + } + } + return true; + } + + template <class _Lock, class _Rep, class _Period, class _Predicate> + bool wait_on_for(_Lock& __lock, + stop_token __stoken, + const chrono::duration<_Rep, _Period>& __rel_time, + _Predicate __p) + { + auto __abst = std::chrono::steady_clock::now() + __rel_time; + return wait_on_until(__lock, + std::move(__stoken), + __abst, + std::move(__p)); + } +#endif }; } // end inline namespace |