From 4209dfaa7f2e5cdc01ddd592f28f49d640d37d15 Mon Sep 17 00:00:00 2001 From: "Vicente J. Botet Escriba" Date: Sat, 8 Dec 2012 08:15:49 +0000 Subject: [PATCH] Thread: Added make_strict_lock. [SVN r81784] --- .../boost/thread/detail/lockable_wrapper.hpp | 43 +++++++++++++++++++ include/boost/thread/lock_guard.hpp | 28 +----------- include/boost/thread/strict_lock.hpp | 43 +++++++++++++++++-- test/Jamfile.v2 | 4 +- .../nested_strict_lock/copy_ctor_fail.cpp | 4 +- .../make_nested_strict_lock_pass.cpp | 4 +- .../strict_lock/make_strict_lock_pass.cpp | 2 +- 7 files changed, 91 insertions(+), 37 deletions(-) create mode 100644 include/boost/thread/detail/lockable_wrapper.hpp diff --git a/include/boost/thread/detail/lockable_wrapper.hpp b/include/boost/thread/detail/lockable_wrapper.hpp new file mode 100644 index 00000000..71b6dfbf --- /dev/null +++ b/include/boost/thread/detail/lockable_wrapper.hpp @@ -0,0 +1,43 @@ +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// (C) Copyright 2012 Vicente J. Botet Escriba + +#ifndef BOOST_THREAD_DETAIL_LOCKABLE_WRAPPER_HPP +#define BOOST_THREAD_DETAIL_LOCKABLE_WRAPPER_HPP + +#if ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST +#include +#endif +#include + +namespace boost +{ + +#if ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST + namespace thread_detail + { + template + struct lockable_wrapper + { + Mutex* m; + explicit lockable_wrapper(Mutex& m_) : + m(&m_) + {} + }; + template + struct lockable_adopt_wrapper + { + Mutex* m; + explicit lockable_adopt_wrapper(Mutex& m_) : + m(&m_) + {} + }; + } +#endif + +} + +#include + +#endif // header diff --git a/include/boost/thread/lock_guard.hpp b/include/boost/thread/lock_guard.hpp index e24c8456..a3007a8e 100644 --- a/include/boost/thread/lock_guard.hpp +++ b/include/boost/thread/lock_guard.hpp @@ -9,42 +9,18 @@ #include #include +#include #include #if ! defined BOOST_THREAD_PROVIDES_NESTED_LOCKS #include -#endif #include -#include -#if ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST -#include #endif + #include namespace boost { -#if ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST - namespace thread_detail - { - template - struct lockable_wrapper - { - Mutex* m; - explicit lockable_wrapper(Mutex& m_) : - m(&m_) - {} - }; - template - struct lockable_adopt_wrapper - { - Mutex* m; - explicit lockable_adopt_wrapper(Mutex& m_) : - m(&m_) - {} - }; - } -#endif - template class lock_guard { diff --git a/include/boost/thread/strict_lock.hpp b/include/boost/thread/strict_lock.hpp index b6808a34..b4909cfd 100644 --- a/include/boost/thread/strict_lock.hpp +++ b/include/boost/thread/strict_lock.hpp @@ -7,6 +7,7 @@ #define BOOST_THREAD_STRICT_LOCK_HPP #include +#include #include #include #include @@ -48,6 +49,15 @@ namespace boost mtx.lock(); } /*< locks on construction >*/ + +#if ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST + strict_lock(std::initializer_list > l_) : + mtx_(*(const_cast*>(l_.begin())->m)) + { + mtx_.lock(); + } +#endif + /** * Destructor * @@ -97,7 +107,7 @@ namespace boost /** * A nested strict lock is a scoped lock guard ensuring the mutex is locked on its - * scope, by taking ownership of an nesting lock, and locking the mutex on construction if not already locked + * scope, by taking ownership of an nesting lock, locking the mutex on construction if not already locked * and restoring the ownership to the nesting lock on destruction. */ //[nested_strict_lock @@ -117,8 +127,8 @@ namespace boost * * __Requires: lk.mutex() != null_ptr * __Effects: Stores the reference to the lock parameter and takes ownership on it. - * If the lock doesn't owns the mutex @mtx lock it. - * __Postconditions: @c owns_lock() + * If the lock doesn't owns the mutex @c mtx lock it. + * __Postconditions: @c owns_lock(lk.mutex()) * __StrongException * __Throws: * @@ -127,7 +137,7 @@ namespace boost * - Any exception that @c lk.lock() can throw. * */ - nested_strict_lock(Lock& lk) : + explicit nested_strict_lock(Lock& lk) : lk_(lk) /*< Store reference to lk >*/ { /*< Define BOOST_THREAD_DONT_CHECK_PRECONDITIONS if you don't want to check lk ownership >*/ @@ -138,6 +148,19 @@ namespace boost tmp_lk_ = move(lk); /*< Move ownership to temporary lk >*/ } +#if ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST + nested_strict_lock(std::initializer_list > l_) : + lk_(*(const_cast*>(l_.begin())->m)) + { + /*< Define BOOST_THREAD_DONT_CHECK_PRECONDITIONS if you don't want to check lk ownership >*/ + BOOST_THREAD_ASSERT_PRECONDITION( lk_.mutex() != 0, + lock_error() + ); + if (!lk_.owns_lock()) lk_.lock(); /*< ensures it is locked >*/ + tmp_lk_ = move(lk_); /*< Move ownership to temporary lk >*/ + } +#endif + /** * Destructor * @@ -180,6 +203,18 @@ public: { }; +#if ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST + template + strict_lock make_strict_lock(Lockable& mtx) + { + return { thread_detail::lockable_wrapper(mtx) }; + } + template + nested_strict_lock make_nested_strict_lock(Lock& lk) + { + return { thread_detail::lockable_wrapper(lk) }; + } +#endif } #include diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 639a7f48..fae1c972 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -480,7 +480,7 @@ rule thread-compile-fail ( sources : reqs * : name ) [ thread-run2-noit ./sync/mutual_exclusion/locks/strict_lock/default_pass.cpp : strict_lock__cons__default_p ] [ thread-run2-noit ./sync/mutual_exclusion/locks/strict_lock/owns_lock_pass.cpp : strict_lock__owns_lock_p ] [ thread-run2-noit ./sync/mutual_exclusion/locks/strict_lock/types_pass.cpp : strict_lock__types_p ] - #[ thread-run2-noit ./sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp : make_strict_lock_p ] + [ thread-run2-noit ./sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp : make_strict_lock_p ] ; #explicit ts_nested_strict_lock ; @@ -491,7 +491,7 @@ rule thread-compile-fail ( sources : reqs * : name ) [ thread-run2-noit ./sync/mutual_exclusion/locks/nested_strict_lock/default_pass.cpp : nested_strict_lock__cons__default_p ] [ thread-run2-noit ./sync/mutual_exclusion/locks/nested_strict_lock/owns_lock_pass.cpp : nested_strict_lock__owns_lock_p ] [ thread-run2-noit ./sync/mutual_exclusion/locks/nested_strict_lock/types_pass.cpp : nested_strict_lock__types_p ] - #[ thread-run2-noit ./sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp : make_nested_strict_lock_p ] + [ thread-run2-noit ./sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp : make_nested_strict_lock_p ] ; diff --git a/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_ctor_fail.cpp b/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_ctor_fail.cpp index b8826baf..1c0abf94 100755 --- a/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_ctor_fail.cpp +++ b/test/sync/mutual_exclusion/locks/nested_strict_lock/copy_ctor_fail.cpp @@ -20,8 +20,8 @@ boost::mutex m1; int main() { - boost::nested_strict_lock lk0(m0); - boost::nested_strict_lock lk1 = lk0; + boost::nested_strict_lock > lk0(m0); + boost::nested_strict_lock > lk1 = lk0; } #include "../../../../remove_error_code_unused_warning.hpp" diff --git a/test/sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp b/test/sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp index 00b8c93c..834d52d2 100644 --- a/test/sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp +++ b/test/sync/mutual_exclusion/locks/nested_strict_lock/make_nested_strict_lock_pass.cpp @@ -30,7 +30,7 @@ typedef boost::chrono::nanoseconds ns; boost::mutex m; -#if ! defined(BOOST_NO_CXX11_AUTO) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST && BOOST_THREAD_USES_CHRONO +#if ! defined(BOOST_NO_CXX11_AUTO) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST && defined BOOST_THREAD_USES_CHRONO void f() { @@ -38,7 +38,7 @@ void f() time_point t1; boost::unique_lock lg(m); { - const auto&& nlg = boost::make_strict_lock(lg); (void)nlg; + const auto&& nlg = boost::make_nested_strict_lock(lg); (void)nlg; t1 = Clock::now(); BOOST_THREAD_TRACE; } diff --git a/test/sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp b/test/sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp index d3261be2..1f4af5ee 100644 --- a/test/sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp +++ b/test/sync/mutual_exclusion/locks/strict_lock/make_strict_lock_pass.cpp @@ -29,7 +29,7 @@ typedef boost::chrono::nanoseconds ns; boost::mutex m; -#if ! defined(BOOST_NO_CXX11_AUTO) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST && BOOST_THREAD_USES_CHRONO +#if ! defined(BOOST_NO_CXX11_AUTO) && ! defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && ! defined BOOST_NO_CXX11_HDR_INITIALIZER_LIST && defined BOOST_THREAD_USES_CHRONO void f() {