X-Git-Url: http://git.sourceforge.jp/view?p=pf3gnuchains%2Fgcc-fork.git;a=blobdiff_plain;f=libstdc%2B%2B-v3%2Finclude%2Fstd%2Fmutex;h=f3848d09c0220553aeaa6fc06be312b02e241c99;hp=e4ceaf2aac893a83b3f3b3bbaa88dc06590a0f17;hb=c643ba1a340de0fa8a5fffa1993b5d90c5243a50;hpb=cdfcd28789dbd886520e846de511207da2171e55 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 #else +#include #include #include #include @@ -601,9 +602,81 @@ namespace std swap(unique_lock<_Mutex>& __x, unique_lock<_Mutex>&& __y) { __x.swap(__y); } - template + template + struct __unlock_impl + { + template + 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 + static void + __do_unlock(tuple<_Lock&...>&) + { } + }; + + template + struct __try_lock_impl + { + template + 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 + struct __try_lock_impl<_Idx, false> + { + template + 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 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 void