diff options
| author | cfairles <cfairles@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-09-28 09:05:07 +0000 |
|---|---|---|
| committer | cfairles <cfairles@138bc75d-0d04-0410-961f-82ee72b054a4> | 2008-09-28 09:05:07 +0000 |
| commit | c643ba1a340de0fa8a5fffa1993b5d90c5243a50 (patch) | |
| tree | c5702d2ed3103c739f4bd2b861ccf12b63986f79 /libstdc++-v3/include/std/mutex | |
| parent | cdfcd28789dbd886520e846de511207da2171e55 (diff) | |
| download | ppe42-gcc-c643ba1a340de0fa8a5fffa1993b5d90c5243a50.tar.gz ppe42-gcc-c643ba1a340de0fa8a5fffa1993b5d90c5243a50.zip | |
2008-09-28 Chris Fairles <cfairles@gcc.gnu.org>
* include/std/mutex (try_lock): Implement generic try_lock.
* testsuite/30_threads/try_lock/1.cc: New.
* testsuite/30_threads/try_lock/2.cc: Likewise.
* testsuite/30_threads/try_lock/3.cc: Likewise.
* testsuite/30_threads/mutex/cons/assign_neg.cc: Adjust line numbers.
* testsuite/30_threads/mutex/cons/copy_neg.cc: Likewise.
* testsuite/30_threads/timed_mutex/cons/assign_neg.cc: Likewise.
* testsuite/30_threads/timed_mutex/cons/copy_neg.cc: Likewise.
* testsuite/30_threads/recursive_mutex/cons/assign_neg.cc: Likewise.
* testsuite/30_threads/recursive_mutex/cons/copy_neg.cc: Likewise.
* testsuite/30_threads/recursive_timed_mutex/cons/assign_neg.cc:
Likewise.
* testsuite/30_threads/recursive_timed_mutex/cons/copy_neg.cc: Likewise.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@140729 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'libstdc++-v3/include/std/mutex')
| -rw-r--r-- | libstdc++-v3/include/std/mutex | 77 |
1 files changed, 75 insertions, 2 deletions
diff --git a/libstdc++-v3/include/std/mutex b/libstdc++-v3/include/std/mutex index e4ceaf2aac8..f3848d09c02 100644 --- a/libstdc++-v3/include/std/mutex +++ b/libstdc++-v3/include/std/mutex @@ -41,6 +41,7 @@ # include <c++0x_warning.h> #else +#include <tuple> #include <cstddef> #include <chrono> #include <exception> @@ -601,9 +602,81 @@ namespace std swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>&& __y) { __x.swap(__y); } - template<typename _L1, typename _L2, typename ..._L3> + template<int _Idx> + struct __unlock_impl + { + template<typename... _Lock> + static void + __do_unlock(tuple<_Lock&...>& __locks) + { + std::get<_Idx>(__locks).unlock(); + __unlock_impl<_Idx - 1>::__do_unlock(__locks); + } + }; + + template<> + struct __unlock_impl<-1> + { + template<typename... _Lock> + static void + __do_unlock(tuple<_Lock&...>&) + { } + }; + + template<int _Idx, bool _Continue = true> + struct __try_lock_impl + { + template<typename... _Lock> + static int + __do_try_lock(tuple<_Lock&...>& __locks) + { + if(std::get<_Idx>(__locks).try_lock()) + { + return __try_lock_impl<_Idx + 1, + _Idx + 2 < sizeof...(_Lock)>::__do_try_lock(__locks); + } + else + { + __unlock_impl<_Idx>::__do_unlock(__locks); + return _Idx; + } + } + }; + + template<int _Idx> + struct __try_lock_impl<_Idx, false> + { + template<typename... _Lock> + static int + __do_try_lock(tuple<_Lock&...>& __locks) + { + if(std::get<_Idx>(__locks).try_lock()) + return -1; + else + { + __unlock_impl<_Idx>::__do_unlock(__locks); + return _Idx; + } + } + }; + + /** @brief Generic try_lock. + * @param __l1 Meets Mutex requirements (try_lock() may throw). + * @param __l2 Meets Mutex requirements (try_lock() may throw). + * @param __l3 Meets Mutex requirements (try_lock() may throw). + * @return Returns -1 if all try_lock() calls return true. Otherwise returns + * a 0-based index corresponding to the argument that returned false. + * @post Either all arguments are locked, or none will be. + * + * Sequentially calls try_lock() on each argument. + */ + template<typename _Lock1, typename _Lock2, typename... _Lock3> int - try_lock(_L1& __l1, _L2& __l2, _L3&... __l3); + try_lock(_Lock1& __l1, _Lock2& __l2, _Lock3&... __l3) + { + tuple<_Lock1&, _Lock2&, _Lock3&...> __locks(__l1, __l2, __l3...); + return __try_lock_impl<0>::__do_try_lock(__locks); + } template<typename _L1, typename _L2, typename ..._L3> void |

