1 // Distributed under the Boost Software License, Version 1.0. (See
2 // accompanying file LICENSE_1_0.txt or copy at
3 // http://www.boost.org/LICENSE_1_0.txt)
4 // (C) Copyright 2007 Anthony Williams
5 #ifndef BOOST_THREAD_LOCKS_HPP
6 #define BOOST_THREAD_LOCKS_HPP
7 #include <boost/thread/detail/config.hpp>
8 #include <boost/thread/exceptions.hpp>
9 #include <boost/thread/detail/move.hpp>
12 #include <boost/thread/thread_time.hpp>
13 #include <boost/detail/workaround.hpp>
15 #include <boost/config/abi_prefix.hpp>
21 #if defined(BOOST_NO_SFINAE) || \
22 BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) || \
23 BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
24 #define BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
27 #ifndef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
31 struct has_member_lock
33 typedef char true_type
;
40 static true_type
has_member(U
*,void (U::*dummy
)()=&U::lock
);
41 static false_type
has_member(void*);
43 BOOST_STATIC_CONSTANT(bool, value
=sizeof(has_member_lock
<T
>::has_member((T
*)NULL
))==sizeof(true_type
));
47 struct has_member_unlock
49 typedef char true_type
;
56 static true_type
has_member(U
*,void (U::*dummy
)()=&U::unlock
);
57 static false_type
has_member(void*);
59 BOOST_STATIC_CONSTANT(bool, value
=sizeof(has_member_unlock
<T
>::has_member((T
*)NULL
))==sizeof(true_type
));
63 struct has_member_try_lock
65 typedef char true_type
;
72 static true_type
has_member(U
*,bool (U::*dummy
)()=&U::try_lock
);
73 static false_type
has_member(void*);
75 BOOST_STATIC_CONSTANT(bool, value
=sizeof(has_member_try_lock
<T
>::has_member((T
*)NULL
))==sizeof(true_type
));
84 BOOST_STATIC_CONSTANT(bool, value
= detail::has_member_lock
<T
>::value
&&
85 detail::has_member_unlock
<T
>::value
&&
86 detail::has_member_try_lock
<T
>::value
);
93 BOOST_STATIC_CONSTANT(bool, value
= false);
104 const defer_lock_t defer_lock
={};
105 const try_to_lock_t try_to_lock
={};
106 const adopt_lock_t adopt_lock
={};
108 template<typename Mutex
>
111 template<typename Mutex
>
114 template<typename Mutex
>
119 template<typename Mutex
>
120 class try_lock_wrapper
;
123 #ifdef BOOST_THREAD_NO_AUTO_DETECT_MUTEX_TYPES
125 struct is_mutex_type
<unique_lock
<T
> >
127 BOOST_STATIC_CONSTANT(bool, value
= true);
131 struct is_mutex_type
<shared_lock
<T
> >
133 BOOST_STATIC_CONSTANT(bool, value
= true);
137 struct is_mutex_type
<upgrade_lock
<T
> >
139 BOOST_STATIC_CONSTANT(bool, value
= true);
143 struct is_mutex_type
<detail::try_lock_wrapper
<T
> >
145 BOOST_STATIC_CONSTANT(bool, value
= true);
150 class recursive_mutex
;
151 class recursive_timed_mutex
;
155 struct is_mutex_type
<mutex
>
157 BOOST_STATIC_CONSTANT(bool, value
= true);
160 struct is_mutex_type
<timed_mutex
>
162 BOOST_STATIC_CONSTANT(bool, value
= true);
165 struct is_mutex_type
<recursive_mutex
>
167 BOOST_STATIC_CONSTANT(bool, value
= true);
170 struct is_mutex_type
<recursive_timed_mutex
>
172 BOOST_STATIC_CONSTANT(bool, value
= true);
175 struct is_mutex_type
<shared_mutex
>
177 BOOST_STATIC_CONSTANT(bool, value
= true);
182 template<typename Mutex
>
188 explicit lock_guard(lock_guard
&);
189 lock_guard
& operator=(lock_guard
&);
191 explicit lock_guard(Mutex
& m_
):
196 lock_guard(Mutex
& m_
,adopt_lock_t
):
206 template<typename Mutex
>
212 unique_lock(unique_lock
&);
213 explicit unique_lock(upgrade_lock
<Mutex
>&);
214 unique_lock
& operator=(unique_lock
&);
215 unique_lock
& operator=(upgrade_lock
<Mutex
>& other
);
218 m(0),is_locked(false)
221 explicit unique_lock(Mutex
& m_
):
222 m(&m_
),is_locked(false)
226 unique_lock(Mutex
& m_
,adopt_lock_t
):
227 m(&m_
),is_locked(true)
229 unique_lock(Mutex
& m_
,defer_lock_t
):
230 m(&m_
),is_locked(false)
232 unique_lock(Mutex
& m_
,try_to_lock_t
):
233 m(&m_
),is_locked(false)
237 template<typename TimeDuration
>
238 unique_lock(Mutex
& m_
,TimeDuration
const& target_time
):
239 m(&m_
),is_locked(false)
241 timed_lock(target_time
);
243 unique_lock(Mutex
& m_
,system_time
const& target_time
):
244 m(&m_
),is_locked(false)
246 timed_lock(target_time
);
248 #ifdef BOOST_HAS_RVALUE_REFS
249 unique_lock(unique_lock
&& other
):
250 m(other
.m
),is_locked(other
.is_locked
)
252 other
.is_locked
=false;
255 explicit unique_lock(upgrade_lock
<Mutex
>&& other
);
257 unique_lock
<Mutex
>&& move()
259 return static_cast<unique_lock
<Mutex
>&&>(*this);
263 unique_lock
& operator=(unique_lock
<Mutex
>&& other
)
265 unique_lock
temp(other
);
270 unique_lock
& operator=(upgrade_lock
<Mutex
>&& other
)
272 unique_lock
temp(other
);
276 void swap(unique_lock
&& other
)
278 std::swap(m
,other
.m
);
279 std::swap(is_locked
,other
.is_locked
);
282 unique_lock(detail::thread_move_t
<unique_lock
<Mutex
> > other
):
283 m(other
->m
),is_locked(other
->is_locked
)
285 other
->is_locked
=false;
288 unique_lock(detail::thread_move_t
<upgrade_lock
<Mutex
> > other
);
290 operator detail::thread_move_t
<unique_lock
<Mutex
> >()
295 detail::thread_move_t
<unique_lock
<Mutex
> > move()
297 return detail::thread_move_t
<unique_lock
<Mutex
> >(*this);
300 unique_lock
& operator=(detail::thread_move_t
<unique_lock
<Mutex
> > other
)
302 unique_lock
temp(other
);
307 unique_lock
& operator=(detail::thread_move_t
<upgrade_lock
<Mutex
> > other
)
309 unique_lock
temp(other
);
313 void swap(unique_lock
& other
)
315 std::swap(m
,other
.m
);
316 std::swap(is_locked
,other
.is_locked
);
318 void swap(detail::thread_move_t
<unique_lock
<Mutex
> > other
)
320 std::swap(m
,other
->m
);
321 std::swap(is_locked
,other
->is_locked
);
336 throw boost::lock_error();
345 throw boost::lock_error();
347 is_locked
=m
->try_lock();
350 template<typename TimeDuration
>
351 bool timed_lock(TimeDuration
const& relative_time
)
353 is_locked
=m
->timed_lock(relative_time
);
357 bool timed_lock(::boost::system_time
const& absolute_time
)
359 is_locked
=m
->timed_lock(absolute_time
);
362 bool timed_lock(::boost::xtime
const& absolute_time
)
364 is_locked
=m
->timed_lock(absolute_time
);
371 throw boost::lock_error();
377 typedef void (unique_lock::*bool_type
)();
378 operator bool_type() const
380 return is_locked
?&unique_lock::lock
:0;
382 bool operator!() const
386 bool owns_lock() const
404 friend class shared_lock
<Mutex
>;
405 friend class upgrade_lock
<Mutex
>;
408 #ifdef BOOST_HAS_RVALUE_REFS
409 template<typename Mutex
>
410 void swap(unique_lock
<Mutex
>&& lhs
,unique_lock
<Mutex
>&& rhs
)
415 template<typename Mutex
>
416 void swap(unique_lock
<Mutex
>& lhs
,unique_lock
<Mutex
>& rhs
)
422 #ifdef BOOST_HAS_RVALUE_REFS
423 template<typename Mutex
>
424 inline unique_lock
<Mutex
>&& move(unique_lock
<Mutex
>&& ul
)
430 template<typename Mutex
>
437 explicit shared_lock(shared_lock
&);
438 shared_lock
& operator=(shared_lock
&);
441 m(0),is_locked(false)
444 explicit shared_lock(Mutex
& m_
):
445 m(&m_
),is_locked(false)
449 shared_lock(Mutex
& m_
,adopt_lock_t
):
450 m(&m_
),is_locked(true)
452 shared_lock(Mutex
& m_
,defer_lock_t
):
453 m(&m_
),is_locked(false)
455 shared_lock(Mutex
& m_
,try_to_lock_t
):
456 m(&m_
),is_locked(false)
460 shared_lock(Mutex
& m_
,system_time
const& target_time
):
461 m(&m_
),is_locked(false)
463 timed_lock(target_time
);
466 shared_lock(detail::thread_move_t
<shared_lock
<Mutex
> > other
):
467 m(other
->m
),is_locked(other
->is_locked
)
469 other
->is_locked
=false;
473 shared_lock(detail::thread_move_t
<unique_lock
<Mutex
> > other
):
474 m(other
->m
),is_locked(other
->is_locked
)
478 m
->unlock_and_lock_shared();
480 other
->is_locked
=false;
484 shared_lock(detail::thread_move_t
<upgrade_lock
<Mutex
> > other
):
485 m(other
->m
),is_locked(other
->is_locked
)
489 m
->unlock_upgrade_and_lock_shared();
491 other
->is_locked
=false;
495 operator detail::thread_move_t
<shared_lock
<Mutex
> >()
500 detail::thread_move_t
<shared_lock
<Mutex
> > move()
502 return detail::thread_move_t
<shared_lock
<Mutex
> >(*this);
506 shared_lock
& operator=(detail::thread_move_t
<shared_lock
<Mutex
> > other
)
508 shared_lock
temp(other
);
513 shared_lock
& operator=(detail::thread_move_t
<unique_lock
<Mutex
> > other
)
515 shared_lock
temp(other
);
520 shared_lock
& operator=(detail::thread_move_t
<upgrade_lock
<Mutex
> > other
)
522 shared_lock
temp(other
);
527 #ifdef BOOST_HAS_RVALUE_REFS
528 void swap(shared_lock
&& other
)
530 std::swap(m
,other
.m
);
531 std::swap(is_locked
,other
.is_locked
);
534 void swap(shared_lock
& other
)
536 std::swap(m
,other
.m
);
537 std::swap(is_locked
,other
.is_locked
);
539 void swap(boost::detail::thread_move_t
<shared_lock
<Mutex
> > other
)
541 std::swap(m
,other
->m
);
542 std::swap(is_locked
,other
->is_locked
);
562 throw boost::lock_error();
571 throw boost::lock_error();
573 is_locked
=m
->try_lock_shared();
576 bool timed_lock(boost::system_time
const& target_time
)
580 throw boost::lock_error();
582 is_locked
=m
->timed_lock_shared(target_time
);
585 template<typename Duration
>
586 bool timed_lock(Duration
const& target_time
)
590 throw boost::lock_error();
592 is_locked
=m
->timed_lock_shared(target_time
);
599 throw boost::lock_error();
605 typedef void (shared_lock
<Mutex
>::*bool_type
)();
606 operator bool_type() const
608 return is_locked
?&shared_lock::lock
:0;
610 bool operator!() const
614 bool owns_lock() const
621 #ifdef BOOST_HAS_RVALUE_REFS
622 template<typename Mutex
>
623 void swap(shared_lock
<Mutex
>&& lhs
,shared_lock
<Mutex
>&& rhs
)
628 template<typename Mutex
>
629 void swap(shared_lock
<Mutex
>& lhs
,shared_lock
<Mutex
>& rhs
)
635 template<typename Mutex
>
642 explicit upgrade_lock(upgrade_lock
&);
643 upgrade_lock
& operator=(upgrade_lock
&);
646 m(0),is_locked(false)
649 explicit upgrade_lock(Mutex
& m_
):
650 m(&m_
),is_locked(false)
654 upgrade_lock(Mutex
& m_
,adopt_lock_t
):
655 m(&m_
),is_locked(true)
657 upgrade_lock(Mutex
& m_
,defer_lock_t
):
658 m(&m_
),is_locked(false)
660 upgrade_lock(Mutex
& m_
,try_to_lock_t
):
661 m(&m_
),is_locked(false)
665 upgrade_lock(detail::thread_move_t
<upgrade_lock
<Mutex
> > other
):
666 m(other
->m
),is_locked(other
->is_locked
)
668 other
->is_locked
=false;
672 upgrade_lock(detail::thread_move_t
<unique_lock
<Mutex
> > other
):
673 m(other
->m
),is_locked(other
->is_locked
)
677 m
->unlock_and_lock_upgrade();
679 other
->is_locked
=false;
683 operator detail::thread_move_t
<upgrade_lock
<Mutex
> >()
688 detail::thread_move_t
<upgrade_lock
<Mutex
> > move()
690 return detail::thread_move_t
<upgrade_lock
<Mutex
> >(*this);
694 upgrade_lock
& operator=(detail::thread_move_t
<upgrade_lock
<Mutex
> > other
)
696 upgrade_lock
temp(other
);
701 upgrade_lock
& operator=(detail::thread_move_t
<unique_lock
<Mutex
> > other
)
703 upgrade_lock
temp(other
);
708 void swap(upgrade_lock
& other
)
710 std::swap(m
,other
.m
);
711 std::swap(is_locked
,other
.is_locked
);
725 throw boost::lock_error();
734 throw boost::lock_error();
736 is_locked
=m
->try_lock_upgrade();
743 throw boost::lock_error();
749 typedef void (upgrade_lock::*bool_type
)();
750 operator bool_type() const
752 return is_locked
?&upgrade_lock::lock
:0;
754 bool operator!() const
758 bool owns_lock() const
762 friend class shared_lock
<Mutex
>;
763 friend class unique_lock
<Mutex
>;
767 #ifdef BOOST_HAS_RVALUE_REFS
768 template<typename Mutex
>
769 unique_lock
<Mutex
>::unique_lock(upgrade_lock
<Mutex
>&& other
):
770 m(other
.m
),is_locked(other
.is_locked
)
772 other
.is_locked
=false;
775 m
.unlock_upgrade_and_lock();
779 template<typename Mutex
>
780 unique_lock
<Mutex
>::unique_lock(detail::thread_move_t
<upgrade_lock
<Mutex
> > other
):
781 m(other
->m
),is_locked(other
->is_locked
)
783 other
->is_locked
=false;
786 m
->unlock_upgrade_and_lock();
790 template <class Mutex
>
791 class upgrade_to_unique_lock
794 upgrade_lock
<Mutex
>* source
;
795 unique_lock
<Mutex
> exclusive
;
797 explicit upgrade_to_unique_lock(upgrade_to_unique_lock
&);
798 upgrade_to_unique_lock
& operator=(upgrade_to_unique_lock
&);
800 explicit upgrade_to_unique_lock(upgrade_lock
<Mutex
>& m_
):
801 source(&m_
),exclusive(move(*source
))
803 ~upgrade_to_unique_lock()
807 *source
=move(exclusive
);
811 upgrade_to_unique_lock(detail::thread_move_t
<upgrade_to_unique_lock
<Mutex
> > other
):
812 source(other
->source
),exclusive(move(other
->exclusive
))
817 upgrade_to_unique_lock
& operator=(detail::thread_move_t
<upgrade_to_unique_lock
<Mutex
> > other
)
819 upgrade_to_unique_lock
temp(other
);
823 void swap(upgrade_to_unique_lock
& other
)
825 std::swap(source
,other
.source
);
826 exclusive
.swap(other
.exclusive
);
828 typedef void (upgrade_to_unique_lock::*bool_type
)(upgrade_to_unique_lock
&);
829 operator bool_type() const
831 return exclusive
.owns_lock()?&upgrade_to_unique_lock::swap
:0;
833 bool operator!() const
837 bool owns_lock() const
839 return exclusive
.owns_lock();
845 template<typename Mutex
>
846 class try_lock_wrapper
:
847 private unique_lock
<Mutex
>
849 typedef unique_lock
<Mutex
> base
;
854 explicit try_lock_wrapper(Mutex
& m
):
858 try_lock_wrapper(Mutex
& m_
,adopt_lock_t
):
861 try_lock_wrapper(Mutex
& m_
,defer_lock_t
):
864 try_lock_wrapper(Mutex
& m_
,try_to_lock_t
):
867 try_lock_wrapper(detail::thread_move_t
<try_lock_wrapper
<Mutex
> > other
):
868 base(detail::thread_move_t
<base
>(*other
))
871 operator detail::thread_move_t
<try_lock_wrapper
<Mutex
> >()
876 detail::thread_move_t
<try_lock_wrapper
<Mutex
> > move()
878 return detail::thread_move_t
<try_lock_wrapper
<Mutex
> >(*this);
881 try_lock_wrapper
& operator=(detail::thread_move_t
<try_lock_wrapper
<Mutex
> > other
)
883 try_lock_wrapper
temp(other
);
888 #ifdef BOOST_HAS_RVALUE_REFS
889 void swap(try_lock_wrapper
&& other
)
894 void swap(try_lock_wrapper
& other
)
898 void swap(detail::thread_move_t
<try_lock_wrapper
<Mutex
> > other
)
910 return base::try_lock();
916 bool owns_lock() const
918 return base::owns_lock();
922 return base::mutex();
926 return base::release();
928 bool operator!() const
930 return !this->owns_lock();
933 typedef typename
base::bool_type bool_type
;
934 operator bool_type() const
936 return base::operator bool_type();
940 #ifdef BOOST_HAS_RVALUE_REFS
941 template<typename Mutex
>
942 void swap(try_lock_wrapper
<Mutex
>&& lhs
,try_lock_wrapper
<Mutex
>&& rhs
)
947 template<typename Mutex
>
948 void swap(try_lock_wrapper
<Mutex
>& lhs
,try_lock_wrapper
<Mutex
>& rhs
)
954 template<typename MutexType1
,typename MutexType2
>
955 unsigned try_lock_internal(MutexType1
& m1
,MutexType2
& m2
)
957 boost::unique_lock
<MutexType1
> l1(m1
,boost::try_to_lock
);
970 template<typename MutexType1
,typename MutexType2
,typename MutexType3
>
971 unsigned try_lock_internal(MutexType1
& m1
,MutexType2
& m2
,MutexType3
& m3
)
973 boost::unique_lock
<MutexType1
> l1(m1
,boost::try_to_lock
);
978 if(unsigned const failed_lock
=try_lock_internal(m2
,m3
))
980 return failed_lock
+1;
987 template<typename MutexType1
,typename MutexType2
,typename MutexType3
,
989 unsigned try_lock_internal(MutexType1
& m1
,MutexType2
& m2
,MutexType3
& m3
,
992 boost::unique_lock
<MutexType1
> l1(m1
,boost::try_to_lock
);
997 if(unsigned const failed_lock
=try_lock_internal(m2
,m3
,m4
))
999 return failed_lock
+1;
1005 template<typename MutexType1
,typename MutexType2
,typename MutexType3
,
1006 typename MutexType4
,typename MutexType5
>
1007 unsigned try_lock_internal(MutexType1
& m1
,MutexType2
& m2
,MutexType3
& m3
,
1008 MutexType4
& m4
,MutexType5
& m5
)
1010 boost::unique_lock
<MutexType1
> l1(m1
,boost::try_to_lock
);
1015 if(unsigned const failed_lock
=try_lock_internal(m2
,m3
,m4
,m5
))
1017 return failed_lock
+1;
1024 template<typename MutexType1
,typename MutexType2
>
1025 unsigned lock_helper(MutexType1
& m1
,MutexType2
& m2
)
1027 boost::unique_lock
<MutexType1
> l1(m1
);
1036 template<typename MutexType1
,typename MutexType2
,typename MutexType3
>
1037 unsigned lock_helper(MutexType1
& m1
,MutexType2
& m2
,MutexType3
& m3
)
1039 boost::unique_lock
<MutexType1
> l1(m1
);
1040 if(unsigned const failed_lock
=try_lock_internal(m2
,m3
))
1048 template<typename MutexType1
,typename MutexType2
,typename MutexType3
,
1049 typename MutexType4
>
1050 unsigned lock_helper(MutexType1
& m1
,MutexType2
& m2
,MutexType3
& m3
,
1053 boost::unique_lock
<MutexType1
> l1(m1
);
1054 if(unsigned const failed_lock
=try_lock_internal(m2
,m3
,m4
))
1062 template<typename MutexType1
,typename MutexType2
,typename MutexType3
,
1063 typename MutexType4
,typename MutexType5
>
1064 unsigned lock_helper(MutexType1
& m1
,MutexType2
& m2
,MutexType3
& m3
,
1065 MutexType4
& m4
,MutexType5
& m5
)
1067 boost::unique_lock
<MutexType1
> l1(m1
);
1068 if(unsigned const failed_lock
=try_lock_internal(m2
,m3
,m4
,m5
))
1080 struct is_mutex_type_wrapper
1083 template<typename MutexType1
,typename MutexType2
>
1084 void lock_impl(MutexType1
& m1
,MutexType2
& m2
,is_mutex_type_wrapper
<true>)
1086 unsigned const lock_count
=2;
1087 unsigned lock_first
=0;
1093 lock_first
=detail::lock_helper(m1
,m2
);
1098 lock_first
=detail::lock_helper(m2
,m1
);
1101 lock_first
=(lock_first
+1)%lock_count
;
1107 template<typename Iterator
>
1108 void lock_impl(Iterator begin
,Iterator end
,is_mutex_type_wrapper
<false>);
1112 template<typename MutexType1
,typename MutexType2
>
1113 void lock(MutexType1
& m1
,MutexType2
& m2
)
1115 detail::lock_impl(m1
,m2
,detail::is_mutex_type_wrapper
<is_mutex_type
<MutexType1
>::value
>());
1118 template<typename MutexType1
,typename MutexType2
>
1119 void lock(const MutexType1
& m1
,MutexType2
& m2
)
1121 detail::lock_impl(m1
,m2
,detail::is_mutex_type_wrapper
<is_mutex_type
<MutexType1
>::value
>());
1124 template<typename MutexType1
,typename MutexType2
>
1125 void lock(MutexType1
& m1
,const MutexType2
& m2
)
1127 detail::lock_impl(m1
,m2
,detail::is_mutex_type_wrapper
<is_mutex_type
<MutexType1
>::value
>());
1130 template<typename MutexType1
,typename MutexType2
>
1131 void lock(const MutexType1
& m1
,const MutexType2
& m2
)
1133 detail::lock_impl(m1
,m2
,detail::is_mutex_type_wrapper
<is_mutex_type
<MutexType1
>::value
>());
1136 template<typename MutexType1
,typename MutexType2
,typename MutexType3
>
1137 void lock(MutexType1
& m1
,MutexType2
& m2
,MutexType3
& m3
)
1139 unsigned const lock_count
=3;
1140 unsigned lock_first
=0;
1146 lock_first
=detail::lock_helper(m1
,m2
,m3
);
1151 lock_first
=detail::lock_helper(m2
,m3
,m1
);
1154 lock_first
=(lock_first
+1)%lock_count
;
1157 lock_first
=detail::lock_helper(m3
,m1
,m2
);
1160 lock_first
=(lock_first
+2)%lock_count
;
1166 template<typename MutexType1
,typename MutexType2
,typename MutexType3
,
1167 typename MutexType4
>
1168 void lock(MutexType1
& m1
,MutexType2
& m2
,MutexType3
& m3
,
1171 unsigned const lock_count
=4;
1172 unsigned lock_first
=0;
1178 lock_first
=detail::lock_helper(m1
,m2
,m3
,m4
);
1183 lock_first
=detail::lock_helper(m2
,m3
,m4
,m1
);
1186 lock_first
=(lock_first
+1)%lock_count
;
1189 lock_first
=detail::lock_helper(m3
,m4
,m1
,m2
);
1192 lock_first
=(lock_first
+2)%lock_count
;
1195 lock_first
=detail::lock_helper(m4
,m1
,m2
,m3
);
1198 lock_first
=(lock_first
+3)%lock_count
;
1204 template<typename MutexType1
,typename MutexType2
,typename MutexType3
,
1205 typename MutexType4
,typename MutexType5
>
1206 void lock(MutexType1
& m1
,MutexType2
& m2
,MutexType3
& m3
,
1207 MutexType4
& m4
,MutexType5
& m5
)
1209 unsigned const lock_count
=5;
1210 unsigned lock_first
=0;
1216 lock_first
=detail::lock_helper(m1
,m2
,m3
,m4
,m5
);
1221 lock_first
=detail::lock_helper(m2
,m3
,m4
,m5
,m1
);
1224 lock_first
=(lock_first
+1)%lock_count
;
1227 lock_first
=detail::lock_helper(m3
,m4
,m5
,m1
,m2
);
1230 lock_first
=(lock_first
+2)%lock_count
;
1233 lock_first
=detail::lock_helper(m4
,m5
,m1
,m2
,m3
);
1236 lock_first
=(lock_first
+3)%lock_count
;
1239 lock_first
=detail::lock_helper(m5
,m1
,m2
,m3
,m4
);
1242 lock_first
=(lock_first
+4)%lock_count
;
1250 template<typename Mutex
,bool x
=is_mutex_type
<Mutex
>::value
>
1251 struct try_lock_impl_return
1256 template<typename Iterator
>
1257 struct try_lock_impl_return
<Iterator
,false>
1259 typedef Iterator type
;
1262 template<typename MutexType1
,typename MutexType2
>
1263 int try_lock_impl(MutexType1
& m1
,MutexType2
& m2
,is_mutex_type_wrapper
<true>)
1265 return ((int)detail::try_lock_internal(m1
,m2
))-1;
1268 template<typename Iterator
>
1269 Iterator
try_lock_impl(Iterator begin
,Iterator end
,is_mutex_type_wrapper
<false>);
1272 template<typename MutexType1
,typename MutexType2
>
1273 typename
detail::try_lock_impl_return
<MutexType1
>::type
try_lock(MutexType1
& m1
,MutexType2
& m2
)
1275 return detail::try_lock_impl(m1
,m2
,detail::is_mutex_type_wrapper
<is_mutex_type
<MutexType1
>::value
>());
1278 template<typename MutexType1
,typename MutexType2
>
1279 typename
detail::try_lock_impl_return
<MutexType1
>::type
try_lock(const MutexType1
& m1
,MutexType2
& m2
)
1281 return detail::try_lock_impl(m1
,m2
,detail::is_mutex_type_wrapper
<is_mutex_type
<MutexType1
>::value
>());
1284 template<typename MutexType1
,typename MutexType2
>
1285 typename
detail::try_lock_impl_return
<MutexType1
>::type
try_lock(MutexType1
& m1
,const MutexType2
& m2
)
1287 return detail::try_lock_impl(m1
,m2
,detail::is_mutex_type_wrapper
<is_mutex_type
<MutexType1
>::value
>());
1290 template<typename MutexType1
,typename MutexType2
>
1291 typename
detail::try_lock_impl_return
<MutexType1
>::type
try_lock(const MutexType1
& m1
,const MutexType2
& m2
)
1293 return detail::try_lock_impl(m1
,m2
,detail::is_mutex_type_wrapper
<is_mutex_type
<MutexType1
>::value
>());
1296 template<typename MutexType1
,typename MutexType2
,typename MutexType3
>
1297 int try_lock(MutexType1
& m1
,MutexType2
& m2
,MutexType3
& m3
)
1299 return ((int)detail::try_lock_internal(m1
,m2
,m3
))-1;
1302 template<typename MutexType1
,typename MutexType2
,typename MutexType3
,typename MutexType4
>
1303 int try_lock(MutexType1
& m1
,MutexType2
& m2
,MutexType3
& m3
,MutexType4
& m4
)
1305 return ((int)detail::try_lock_internal(m1
,m2
,m3
,m4
))-1;
1308 template<typename MutexType1
,typename MutexType2
,typename MutexType3
,typename MutexType4
,typename MutexType5
>
1309 int try_lock(MutexType1
& m1
,MutexType2
& m2
,MutexType3
& m3
,MutexType4
& m4
,MutexType5
& m5
)
1311 return ((int)detail::try_lock_internal(m1
,m2
,m3
,m4
,m5
))-1;
1317 template<typename Iterator
>
1318 struct range_lock_guard
1323 range_lock_guard(Iterator begin_
,Iterator end_
):
1324 begin(begin_
),end(end_
)
1336 for(;begin
!=end
;++begin
)
1343 template<typename Iterator
>
1344 Iterator
try_lock_impl(Iterator begin
,Iterator end
,is_mutex_type_wrapper
<false>)
1351 typedef typename
std::iterator_traits
<Iterator
>::value_type lock_type
;
1352 unique_lock
<lock_type
> guard(*begin
,try_to_lock
);
1354 if(!guard
.owns_lock())
1358 Iterator
const failed
=try_lock(++begin
,end
);
1371 template<typename Iterator
>
1372 void lock_impl(Iterator begin
,Iterator end
,is_mutex_type_wrapper
<false>)
1374 typedef typename
std::iterator_traits
<Iterator
>::value_type lock_type
;
1380 bool start_with_begin
=true;
1381 Iterator second
=begin
;
1383 Iterator next
=second
;
1387 unique_lock
<lock_type
> begin_lock(*begin
,defer_lock
);
1388 if(start_with_begin
)
1391 Iterator
const failed_lock
=try_lock(next
,end
);
1392 if(failed_lock
==end
)
1394 begin_lock
.release();
1397 start_with_begin
=false;
1402 detail::range_lock_guard
<Iterator
> guard(next
,end
);
1403 if(begin_lock
.try_lock())
1405 Iterator
const failed_lock
=try_lock(second
,next
);
1406 if(failed_lock
==next
)
1408 begin_lock
.release();
1412 start_with_begin
=false;
1417 start_with_begin
=true;
1428 #include <boost/config/abi_suffix.hpp>