summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/std/condition_variable
diff options
context:
space:
mode:
authorThomas Rodgers <trodgers@redhat.com>2019-11-15 03:09:19 +0000
committerThomas Rodgers <rodgertq@gcc.gnu.org>2019-11-15 03:09:19 +0000
commit942c4b32b0553378f843e606bb56c417acbdc4be (patch)
tree41fec04827f82dc4850fc993c2d0958d8a12fb02 /libstdc++-v3/include/std/condition_variable
parentf8aea5e37d12e09fef68b854a190f71d6b39e11f (diff)
downloadgcc-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_variable84
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