summaryrefslogtreecommitdiff
path: root/libstdc++-v3/include/std/mutex
diff options
context:
space:
mode:
authorJonathan Wakely <jwakely@redhat.com>2017-03-05 18:38:35 +0000
committerJonathan Wakely <redi@gcc.gnu.org>2017-03-05 18:38:35 +0000
commitf620e1d5c84586f6e60bf5350946ea4a75154ff4 (patch)
treea3d7288f3ed77f2935a5140ef1f8c0f45a0d5539 /libstdc++-v3/include/std/mutex
parentd8b4baeb45c2727156e6d14e1dee16e078c0a727 (diff)
downloadgcc-f620e1d5c84586f6e60bf5350946ea4a75154ff4.tar.gz
Add std::scoped_lock for C++17
* doc/xml/manual/status_cxx2017.xml: Document P0156R2 status. * doc/html/*: Regenerate. * include/std/mutex (scoped_lock): Implement new C++17 template. * testsuite/30_threads/scoped_lock/cons/1.cc: New test. * testsuite/30_threads/scoped_lock/requirements/ explicit_instantiation.cc: New test. * testsuite/30_threads/scoped_lock/requirements/typedefs.cc: New test. From-SVN: r245903
Diffstat (limited to 'libstdc++-v3/include/std/mutex')
-rw-r--r--libstdc++-v3/include/std/mutex68
1 files changed, 68 insertions, 0 deletions
diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex
index d6f3899e4f6..6c3f92022be 100644
--- a/libstdc++-v3/include/std/mutex
+++ b/libstdc++-v3/include/std/mutex
@@ -556,6 +556,74 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
}
}
+#if __cplusplus > 201402L
+#define __cpp_lib_scoped_lock 201703
+ /** @brief A scoped lock type for multiple lockable objects.
+ *
+ * A scoped_lock controls mutex ownership within a scope, releasing
+ * ownership in the destructor.
+ */
+ template<typename... _MutexTypes>
+ class scoped_lock
+ {
+ public:
+ explicit scoped_lock(_MutexTypes&... __m) : _M_devices(std::tie(__m...))
+ { std::lock(__m...); }
+
+ explicit scoped_lock(_MutexTypes&... __m, adopt_lock_t) noexcept
+ : _M_devices(std::tie(__m...))
+ { } // calling thread owns mutex
+
+ ~scoped_lock()
+ {
+ std::apply([](_MutexTypes&... __m) {
+ char __i[] __attribute__((__unused__)) = { (__m.unlock(), 0)... };
+ }, _M_devices);
+ }
+
+ scoped_lock(const scoped_lock&) = delete;
+ scoped_lock& operator=(const scoped_lock&) = delete;
+
+ private:
+ tuple<_MutexTypes&...> _M_devices;
+ };
+
+ template<>
+ class scoped_lock<>
+ {
+ public:
+ explicit scoped_lock() = default;
+ explicit scoped_lock(adopt_lock_t) noexcept { }
+ ~scoped_lock() = default;
+
+ scoped_lock(const scoped_lock&) = delete;
+ scoped_lock& operator=(const scoped_lock&) = delete;
+ };
+
+ template<typename _Mutex>
+ class scoped_lock<_Mutex>
+ {
+ public:
+ using mutex_type = _Mutex;
+
+ explicit scoped_lock(mutex_type& __m) : _M_device(__m)
+ { _M_device.lock(); }
+
+ explicit scoped_lock(mutex_type& __m, adopt_lock_t) noexcept
+ : _M_device(__m)
+ { } // calling thread owns mutex
+
+ ~scoped_lock()
+ { _M_device.unlock(); }
+
+ scoped_lock(const scoped_lock&) = delete;
+ scoped_lock& operator=(const scoped_lock&) = delete;
+
+ private:
+ mutex_type& _M_device;
+ };
+#endif // C++17
+
#ifdef _GLIBCXX_HAS_GTHREADS
/// once_flag
struct once_flag