9#include "./system_error.hpp"
10#include "./chrono.hpp"
11#include "./condition_variable.hpp"
12#include "./thread.hpp"
20#ifdef _STDEX_NATIVE_CPP11_SUPPORT
22#define _STDEX_DELETED_FUNCTION =delete
23#define _STDEX_NOEXCEPT_FUNCTION noexcept
24#define _STDEX_NOEXCEPT(args) noexcept(args)
28#define _STDEX_DELETED_FUNCTION
29#define _STDEX_NOEXCEPT_FUNCTION throw()
30#define _STDEX_NOEXCEPT(args)
43 pthread_mutex_t _mutex_handle;
45 _mutex_base() _STDEX_NOEXCEPT_FUNCTION
48 int _err = pthread_mutex_init(&_mutex_handle, NULL);
50 _throw_system_error(stdex::errc::errc_t(_err));
53 ~_mutex_base() _STDEX_NOEXCEPT(false)
55 int _err = pthread_mutex_destroy(&_mutex_handle);
57 _throw_system_error(stdex::errc::errc_t(_err));
61 _mutex_base(
const _mutex_base&) _STDEX_DELETED_FUNCTION;
62 _mutex_base& operator=(
const _mutex_base&) _STDEX_DELETED_FUNCTION;
65 class _recursive_mutex_base
68 pthread_mutex_t _mutex_handle;
70 _recursive_mutex_base()
72 pthread_mutexattr_t attr;
74 int _err = pthread_mutexattr_init(&attr);
78 _err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
81 _err = pthread_mutex_init(&_mutex_handle, &attr);
87 stdex::make_error_code(stdex::errc::errc_t(_err))
92 ~_recursive_mutex_base() _STDEX_NOEXCEPT(false)
94 int _err = pthread_mutex_destroy(&_mutex_handle);
96 _throw_system_error(stdex::errc::errc_t(_err));
100 _recursive_mutex_base(
const _recursive_mutex_base&) _STDEX_DELETED_FUNCTION;
101 _recursive_mutex_base& operator=(
const _recursive_mutex_base&) _STDEX_DELETED_FUNCTION;
106 private detail::_mutex_base
109 typedef pthread_mutex_t* native_handle_type;
111 mutex() _STDEX_NOEXCEPT_FUNCTION
119 int _err = pthread_mutex_lock(&_mutex_handle);
124 stdex::make_error_code(stdex::errc::errc_t(_err))
128 inline bool try_lock() _STDEX_NOEXCEPT_FUNCTION
131 return (pthread_mutex_trylock(&_mutex_handle) == 0) ? true :
false;
136 int _err = pthread_mutex_unlock(&_mutex_handle);
140 stdex::make_error_code(stdex::errc::errc_t(_err))
144 native_handle_type native_handle() _STDEX_NOEXCEPT_FUNCTION
146 return &_mutex_handle;
151 mutex(
const mutex&) _STDEX_DELETED_FUNCTION;
152 mutex& operator=(
const mutex&) _STDEX_DELETED_FUNCTION;
155 class recursive_mutex :
156 private detail::_recursive_mutex_base
159 typedef pthread_mutex_t* native_handle_type;
169 int _err = pthread_mutex_lock(&_mutex_handle);
174 stdex::make_error_code(stdex::errc::errc_t(_err))
178 inline bool try_lock()
181 return (pthread_mutex_trylock(&_mutex_handle) == 0) ? true :
false;
186 int _err = pthread_mutex_unlock(&_mutex_handle);
190 stdex::make_error_code(stdex::errc::errc_t(_err))
194 native_handle_type native_handle() _STDEX_NOEXCEPT_FUNCTION
196 return &_mutex_handle;
201 recursive_mutex(
const recursive_mutex&) _STDEX_DELETED_FUNCTION;
202 recursive_mutex& operator=(
const recursive_mutex&) _STDEX_DELETED_FUNCTION;
215 extern const adopt_lock_t adopt_lock;
216 extern const defer_lock_t defer_lock;
217 extern const try_to_lock_t try_to_lock;
219 template <
class _Lockbl>
222 typedef _Lockbl mutex_type;
224 explicit lock_guard(mutex_type &_m):
230 lock_guard(mutex_type &_m, adopt_lock_t) _STDEX_NOEXCEPT_FUNCTION:
243 lock_guard(
const lock_guard&) _STDEX_DELETED_FUNCTION;
244 lock_guard& operator=(
const lock_guard&) _STDEX_DELETED_FUNCTION;
247 template<
class _Lockbl>
251 typedef _Lockbl mutex_type;
253 unique_lock() _STDEX_NOEXCEPT_FUNCTION :
258 explicit unique_lock(mutex_type &_m):
266 unique_lock(mutex_type &_m, defer_lock_t) _STDEX_NOEXCEPT_FUNCTION:
271 unique_lock(mutex_type &_m, try_to_lock_t):
273 _owns(_device->try_lock())
276 unique_lock(mutex_type &_m, adopt_lock_t) _STDEX_NOEXCEPT_FUNCTION:
283 template<
class _Clock,
class _Duration>
284 unique_lock(mutex_type &_m,
const chrono::time_point<_Clock, _Duration> &atime):
286 _owns(_device->try_lock_until(atime))
289 template<
class _Rep,
class _Period>
290 unique_lock(mutex_type &_m,
const chrono::duration<_Rep, _Period> &rtime):
292 _owns(_device->try_lock_for(rtime))
328 stdex::make_error_code(errc::operation_not_permitted)
332 stdex::make_error_code(errc::resource_deadlock_would_occur)
345 stdex::make_error_code(errc::operation_not_permitted)
349 stdex::make_error_code(errc::resource_deadlock_would_occur)
353 _owns = _device->try_lock();
358 template<
class _Clock,
class _Duration>
359 bool try_lock_until(
const chrono::time_point<_Clock, _Duration> &atime)
363 stdex::make_error_code(errc::operation_not_permitted)
367 stdex::make_error_code(errc::resource_deadlock_would_occur)
371 _owns = _device->try_lock_until(atime);
376 template<
class _Rep,
class _Period>
377 bool try_lock_for(
const chrono::duration<_Rep, _Period> &rtime)
381 stdex::make_error_code(errc::operation_not_permitted)
385 stdex::make_error_code(errc::resource_deadlock_would_occur)
389 _owns = _device->try_lock_for(rtime);
398 stdex::make_error_code(errc::operation_not_permitted)
407 void swap(unique_lock &other) _STDEX_NOEXCEPT_FUNCTION
410 mutex_type *tmp_value = _device;
411 _device = other._device;
412 other._device = tmp_value;
416 bool tmp_value = _owns;
418 other._owns = tmp_value;
422 mutex_type* release() _STDEX_NOEXCEPT_FUNCTION
424 mutex_type *ret = _device;
430 bool owns_lock() const _STDEX_NOEXCEPT_FUNCTION
435 operator bool() const _STDEX_NOEXCEPT_FUNCTION
440 mutex_type* mutex() const _STDEX_NOEXCEPT_FUNCTION
449 unique_lock(
const unique_lock&) _STDEX_DELETED_FUNCTION;
450 unique_lock& operator=(
const unique_lock&) _STDEX_DELETED_FUNCTION;
454 class recursive_timed_mutex;
459 namespace mutex_type_traits
462 float* pthread_mutex_timedlock(...);
468 _yes_type _pthread_func_tester(
int);
469 _no_type _pthread_func_tester(...);
471 struct _has_pthread_mutex_timedlock
473 static const bool value =
475 _pthread_func_tester(
476 pthread_mutex_timedlock(
477 declval< ::pthread_mutex_t*>(),
478 declval< ::timespec* >()
481 ) ==
sizeof(_yes_type);
485 struct _timed_mutex_with_timedlock
489 template<
class _Rep,
class _Period>
490 static bool try_lock_for(pthread_mutex_t& _mutex_handle,
491 const chrono::duration<_Rep, _Period>& _rtime)
493 typedef chrono::system_clock _clock;
495 _clock::duration _rt =
496 chrono::duration_cast<_clock::duration>(_rtime);
499 ratio_greater<_clock::period, _Period>::value;
502 return try_lock_until1(_mutex_handle, _clock::now() + _rt);
505 template<
class _Duration,
class _MtxHandle>
506 static bool try_lock_until1(_MtxHandle& _mutex_handle,
507 const chrono::time_point<chrono::system_clock, _Duration>& _atime)
509 stdex::timespec _tp_as_ts =
510 chrono::system_clock::to_timespec(_atime);
514 _ts.tv_nsec = _tp_as_ts.tv_nsec;
515 _ts.tv_sec = _tp_as_ts.tv_sec;
518 (pthread_mutex_timedlock(&_mutex_handle, &_ts) == 0);
523 template<
class _Clock,
class _Duration>
524 static bool try_lock_until(pthread_mutex_t& _mutex_handle,
525 const chrono::time_point<_Clock, _Duration>& _atime)
530 typename _Clock::time_point _now = _Clock::now();
532 typename _Clock::duration _rtime = _atime - _now;
533 if (try_lock_for(_mutex_handle, _rtime))
535 _now = _Clock::now();
536 }
while (_atime > _now);
541 template<
class,
bool>
542 class _timed_mutex_impl_base;
546 class _timed_mutex_impl_base<_mutex_base, false>
550 bool operator()()
const {
559 typedef mutex::native_handle_type native_handle_type;
561 ~_timed_mutex_impl_base()
566 unique_lock<mutex> _lk(_mut);
569 _pred._locked = &_locked;
571 _cv.wait(_lk, _pred);
577 lock_guard<mutex> _lk(_mut);
584 template<
class _Rep,
class _Period>
585 bool try_lock_for(
const chrono::duration<_Rep, _Period>& _rtime)
587 unique_lock<mutex> _lk(_mut);
590 _pred._locked = &_locked;
592 if (!_cv.wait_for(_lk, _rtime, _pred))
598 template<
class _Clock,
class _Duration>
599 bool try_lock_until(
const chrono::time_point<_Clock, _Duration>& _atime)
601 unique_lock<mutex> _lk(_mut);
604 _pred._locked = &_locked;
606 if (!_cv.wait_until(_lk, _atime, _pred))
614 lock_guard<mutex> _lk(_mut);
620 native_handle_type native_handle() _STDEX_NOEXCEPT_FUNCTION
622 return _mut.native_handle();
626 _timed_mutex_impl_base() _STDEX_NOEXCEPT_FUNCTION:
633 condition_variable _cv;
638 class _timed_mutex_impl_base<_recursive_mutex_base, false>
645 bool operator()() const _STDEX_NOEXCEPT_FUNCTION
647 return _mx->_count == 0 || _mx->_owner == _caller;
650 const _timed_mutex_impl_base<_recursive_mutex_base, false>* _mx;
654 friend class _timed_mutex_impl_base<_recursive_mutex_base, false>::_Can_lock;
658 typedef mutex::native_handle_type native_handle_type;
660 ~_timed_mutex_impl_base()
668 _can_lock._mx =
this;
669 _can_lock._caller = _id;
671 unique_lock<mutex> _lk(_mut);
672 _cv.wait(_lk, _can_lock);
673 if ((0u - 1u) == _count)
675 stdex::make_error_code(stdex::errc::errc_t(EAGAIN))
686 _can_lock._mx =
this;
687 _can_lock._caller = _id;
689 lock_guard<mutex> _lk(_mut);
692 if ((0u - 1u) == _count)
699 template<
class _Rep,
class _Period>
700 bool try_lock_for(
const chrono::duration<_Rep, _Period>& _rtime)
705 _can_lock._mx =
this;
706 _can_lock._caller = _id;
708 unique_lock<mutex> _lk(_mut);
709 if (!_cv.wait_for(_lk, _rtime, _can_lock))
711 if ((0u - 1u) == _count)
718 template<
class _Clock,
class _Duration>
719 bool try_lock_until(
const chrono::time_point<_Clock, _Duration>& _atime)
724 _can_lock._mx =
this;
725 _can_lock._caller = _id;
727 unique_lock<mutex> _lk(_mut);
728 if (!_cv.wait_until(_lk, _atime, _can_lock))
730 if ((0u - 1u) == _count)
739 lock_guard<mutex> _lk(_mut);
743 _owner = thread::id();
748 native_handle_type native_handle() _STDEX_NOEXCEPT_FUNCTION
750 return _mut.native_handle();
754 _timed_mutex_impl_base() _STDEX_NOEXCEPT_FUNCTION :
761 condition_variable _cv;
765 _timed_mutex_impl_base(
const _timed_mutex_impl_base&) _STDEX_DELETED_FUNCTION;
766 _timed_mutex_impl_base& operator=(
const _timed_mutex_impl_base&) _STDEX_DELETED_FUNCTION;
771 class _timed_mutex_impl_base<_mutex_base, true> :
776 typedef mutex::native_handle_type native_handle_type;
778 ~_timed_mutex_impl_base()
783 int _err = pthread_mutex_lock(&_mutex_handle);
788 stdex::make_error_code(stdex::errc::errc_t(_err))
792 inline bool try_lock() _STDEX_NOEXCEPT_FUNCTION
795 return (pthread_mutex_trylock(&_mutex_handle) == 0) ? true :
false;
798 template <
class _Rep,
class _Period>
799 bool try_lock_for(
const chrono::duration<_Rep, _Period>& _rtime)
801 return _timed_mutex_with_timedlock::try_lock_for(_mutex_handle, _rtime);
804 template <
class _Clock,
class _Duration>
805 bool try_lock_until(
const chrono::time_point<_Clock, _Duration>& _atime)
807 return _timed_mutex_with_timedlock::try_lock_until(_mutex_handle, _atime);
812 pthread_mutex_unlock(&_mutex_handle);
815 native_handle_type native_handle() _STDEX_NOEXCEPT_FUNCTION
817 return &_mutex_handle;
822 _timed_mutex_impl_base() _STDEX_NOEXCEPT_FUNCTION
827 _timed_mutex_impl_base(
const _timed_mutex_impl_base&) _STDEX_DELETED_FUNCTION;
828 _timed_mutex_impl_base& operator=(
const _timed_mutex_impl_base&) _STDEX_DELETED_FUNCTION;
832 class _timed_mutex_impl_base<_recursive_mutex_base, true> :
833 private _recursive_mutex_base
837 typedef mutex::native_handle_type native_handle_type;
839 ~_timed_mutex_impl_base()
844 int _err = pthread_mutex_lock(&_mutex_handle);
849 stdex::make_error_code(stdex::errc::errc_t(_err))
853 inline bool try_lock()
856 return (pthread_mutex_trylock(&_mutex_handle) == 0) ? true :
false;
859 template <
class _Rep,
class _Period>
860 bool try_lock_for(
const chrono::duration<_Rep, _Period>& _rtime)
862 return _timed_mutex_with_timedlock::try_lock_for(_mutex_handle, _rtime);
865 template <
class _Clock,
class _Duration>
866 bool try_lock_until(
const chrono::time_point<_Clock, _Duration>& _atime)
868 return _timed_mutex_with_timedlock::try_lock_until(_mutex_handle, _atime);
874 pthread_mutex_unlock(&_mutex_handle);
877 native_handle_type native_handle() _STDEX_NOEXCEPT_FUNCTION
879 return &_mutex_handle;
884 _timed_mutex_impl_base()
889 _timed_mutex_impl_base(
const _timed_mutex_impl_base&) _STDEX_DELETED_FUNCTION;
890 _timed_mutex_impl_base& operator=(
const _timed_mutex_impl_base&) _STDEX_DELETED_FUNCTION;
894 class _timed_mutex_impl;
897 class _timed_mutex_impl<timed_mutex> :
898 public _timed_mutex_impl_base<
900 mutex_type_traits::_has_pthread_mutex_timedlock::value
904 _timed_mutex_impl() _STDEX_NOEXCEPT_FUNCTION
909 class _timed_mutex_impl<recursive_timed_mutex> :
910 public _timed_mutex_impl_base<
911 _recursive_mutex_base,
912 mutex_type_traits::_has_pthread_mutex_timedlock::value
922 public detail::_timed_mutex_impl<timed_mutex>
925 class recursive_timed_mutex :
926 public detail::_timed_mutex_impl<recursive_timed_mutex>
930 template<
class _Lockbl>
931 inline void swap(stdex::unique_lock<_Lockbl> &lhs, stdex::unique_lock<_Lockbl> &rhs) _STDEX_NOEXCEPT_FUNCTION
938 pthread_mutex_t* _lock_mutex_native_handle(
const unique_lock<mutex>&);
939 bool _lock_owns_lock(
const unique_lock<mutex>&);
953 template <
class _Lockbl1,
class _Lockbl2>
954 unsigned int _try_lock(_Lockbl1 &_m1, _Lockbl2 &_m2)
956 stdex::unique_lock<_Lockbl1> _l1(_m1, stdex::try_to_lock);
968 template <
class _Lockbl1,
class _Lockbl2>
969 unsigned int _lock_helper(_Lockbl1 &_m1, _Lockbl2 &_m2)
971 stdex::unique_lock<_Lockbl1> _l1(_m1);
981#undef _STDEX_TRY_LOCK
982#undef _STDEX_LOCK_HELPER
986#undef _STDEX_ARGS_NAMES
988#define _STDEX_TRY_LOCK(N) \
989 template <class _Lockbl1, _STDEX_TYPES##N > \
990 unsigned int _try_lock(_Lockbl1 &_m1, _STDEX_ARGS##N ) \
992 stdex::unique_lock<_Lockbl1> _l1(_m1, stdex::try_to_lock); \
996 const unsigned int _failed_lock = _try_lock(_STDEX_ARGS_NAMES##N ); \
998 if (_failed_lock > 0) \
999 return _failed_lock + 1; \
1004 template <class _Lockbl1, _STDEX_TYPES##N > \
1005 int try_lock(_Lockbl1 &_m1, _STDEX_ARGS##N ) \
1007 return ((int) _try_lock(_m1, _STDEX_ARGS_NAMES##N )) - 1; \
1010#define _STDEX_LOCK_HELPER(N) \
1011 template <class _Lockbl1, _STDEX_TYPES##N > \
1012 unsigned int _lock_helper(_Lockbl1 &_m1, _STDEX_ARGS##N ) \
1014 stdex::unique_lock<_Lockbl1> _l1(_m1); \
1015 const unsigned int _failed_lock = _try_lock(_STDEX_ARGS_NAMES##N ); \
1016 if (_failed_lock > 0) \
1017 return _failed_lock; \
1025#define _STDEX_TYPES_N(N) class _Lockbl##N
1026#define _STDEX_ARGS_N(N) _Lockbl##N &_m##N
1027#define _STDEX_ARGS_NAMES_N(N) _m##N
1029#define _STDEX_TYPES3 class _Lockbl2, class _Lockbl3
1030#define _STDEX_ARGS3 _Lockbl2 &_m2, _Lockbl3 &_m3
1031#define _STDEX_ARGS_NAMES3 _m2, _m3
1032#define _STDEX_TYPES4 _STDEX_TYPES3 , _STDEX_TYPES_N (4)
1033#define _STDEX_ARGS4 _STDEX_ARGS3 , _STDEX_ARGS_N (4)
1034#define _STDEX_ARGS_NAMES4 _STDEX_ARGS_NAMES3 , _STDEX_ARGS_NAMES_N (4)
1035#define _STDEX_TYPES5 _STDEX_TYPES4 , _STDEX_TYPES_N (5)
1036#define _STDEX_ARGS5 _STDEX_ARGS4 , _STDEX_ARGS_N (5)
1037#define _STDEX_ARGS_NAMES5 _STDEX_ARGS_NAMES4 , _STDEX_ARGS_NAMES_N (5)
1038#define _STDEX_TYPES6 _STDEX_TYPES5 , _STDEX_TYPES_N (6)
1039#define _STDEX_ARGS6 _STDEX_ARGS5 , _STDEX_ARGS_N (6)
1040#define _STDEX_ARGS_NAMES6 _STDEX_ARGS_NAMES5 , _STDEX_ARGS_NAMES_N (6)
1041#define _STDEX_TYPES7 _STDEX_TYPES6 , _STDEX_TYPES_N (7)
1042#define _STDEX_ARGS7 _STDEX_ARGS6 , _STDEX_ARGS_N (7)
1043#define _STDEX_ARGS_NAMES7 _STDEX_ARGS_NAMES6 , _STDEX_ARGS_NAMES_N (7)
1044#define _STDEX_TYPES8 _STDEX_TYPES7 , _STDEX_TYPES_N (8)
1045#define _STDEX_ARGS8 _STDEX_ARGS7 , _STDEX_ARGS_N (8)
1046#define _STDEX_ARGS_NAMES8 _STDEX_ARGS_NAMES7 , _STDEX_ARGS_NAMES_N (8)
1047#define _STDEX_TYPES9 _STDEX_TYPES8 , _STDEX_TYPES_N (9)
1048#define _STDEX_ARGS9 _STDEX_ARGS8 , _STDEX_ARGS_N (9)
1049#define _STDEX_ARGS_NAMES9 _STDEX_ARGS_NAMES8 , _STDEX_ARGS_NAMES_N (9)
1050#define _STDEX_TYPES10 _STDEX_TYPES9 , _STDEX_TYPES_N (10)
1051#define _STDEX_ARGS10 _STDEX_ARGS9 , _STDEX_ARGS_N (10)
1052#define _STDEX_ARGS_NAMES10 _STDEX_ARGS_NAMES9 , _STDEX_ARGS_NAMES_N (10)
1053#define _STDEX_TYPES11 _STDEX_TYPES10, _STDEX_TYPES_N (11)
1054#define _STDEX_ARGS11 _STDEX_ARGS10, _STDEX_ARGS_N (11)
1055#define _STDEX_ARGS_NAMES11 _STDEX_ARGS_NAMES10, _STDEX_ARGS_NAMES_N (11)
1056#define _STDEX_TYPES12 _STDEX_TYPES11, _STDEX_TYPES_N (12)
1057#define _STDEX_ARGS12 _STDEX_ARGS11, _STDEX_ARGS_N (12)
1058#define _STDEX_ARGS_NAMES12 _STDEX_ARGS_NAMES11, _STDEX_ARGS_NAMES_N (12)
1059#define _STDEX_TYPES13 _STDEX_TYPES12, _STDEX_TYPES_N (13)
1060#define _STDEX_ARGS13 _STDEX_ARGS12, _STDEX_ARGS_N (13)
1061#define _STDEX_ARGS_NAMES13 _STDEX_ARGS_NAMES12, _STDEX_ARGS_NAMES_N (13)
1062#define _STDEX_TYPES14 _STDEX_TYPES13, _STDEX_TYPES_N (14)
1063#define _STDEX_ARGS14 _STDEX_ARGS13, _STDEX_ARGS_N (14)
1064#define _STDEX_ARGS_NAMES14 _STDEX_ARGS_NAMES13, _STDEX_ARGS_NAMES_N (14)
1065#define _STDEX_TYPES15 _STDEX_TYPES14, _STDEX_TYPES_N (15)
1066#define _STDEX_ARGS15 _STDEX_ARGS14, _STDEX_ARGS_N (15)
1067#define _STDEX_ARGS_NAMES15 _STDEX_ARGS_NAMES14, _STDEX_ARGS_NAMES_N (15)
1068#define _STDEX_TYPES16 _STDEX_TYPES15, _STDEX_TYPES_N (16)
1069#define _STDEX_ARGS16 _STDEX_ARGS15, _STDEX_ARGS_N (16)
1070#define _STDEX_ARGS_NAMES16 _STDEX_ARGS_NAMES15, _STDEX_ARGS_NAMES_N (16)
1071#define _STDEX_TYPES17 _STDEX_TYPES16, _STDEX_TYPES_N (17)
1072#define _STDEX_ARGS17 _STDEX_ARGS16, _STDEX_ARGS_N (17)
1073#define _STDEX_ARGS_NAMES17 _STDEX_ARGS_NAMES16, _STDEX_ARGS_NAMES_N (17)
1074#define _STDEX_TYPES18 _STDEX_TYPES17, _STDEX_TYPES_N (18)
1075#define _STDEX_ARGS18 _STDEX_ARGS17, _STDEX_ARGS_N (18)
1076#define _STDEX_ARGS_NAMES18 _STDEX_ARGS_NAMES17, _STDEX_ARGS_NAMES_N (18)
1077#define _STDEX_TYPES19 _STDEX_TYPES18, _STDEX_TYPES_N (19)
1078#define _STDEX_ARGS19 _STDEX_ARGS18, _STDEX_ARGS_N (19)
1079#define _STDEX_ARGS_NAMES19 _STDEX_ARGS_NAMES18, _STDEX_ARGS_NAMES_N (19)
1080#define _STDEX_TYPES20 _STDEX_TYPES19, _STDEX_TYPES_N (20)
1081#define _STDEX_ARGS20 _STDEX_ARGS19, _STDEX_ARGS_N (20)
1082#define _STDEX_ARGS_NAMES20 _STDEX_ARGS_NAMES19, _STDEX_ARGS_NAMES_N (20)
1083#define _STDEX_TYPES21 _STDEX_TYPES20, _STDEX_TYPES_N (21)
1084#define _STDEX_ARGS21 _STDEX_ARGS20, _STDEX_ARGS_N (21)
1085#define _STDEX_ARGS_NAMES21 _STDEX_ARGS_NAMES20, _STDEX_ARGS_NAMES_N (21)
1086#define _STDEX_TYPES22 _STDEX_TYPES21, _STDEX_TYPES_N (22)
1087#define _STDEX_ARGS22 _STDEX_ARGS21, _STDEX_ARGS_N (22)
1088#define _STDEX_ARGS_NAMES22 _STDEX_ARGS_NAMES21, _STDEX_ARGS_NAMES_N (22)
1089#define _STDEX_TYPES23 _STDEX_TYPES22, _STDEX_TYPES_N (23)
1090#define _STDEX_ARGS23 _STDEX_ARGS22, _STDEX_ARGS_N (23)
1091#define _STDEX_ARGS_NAMES23 _STDEX_ARGS_NAMES22, _STDEX_ARGS_NAMES_N (23)
1092#define _STDEX_TYPES24 _STDEX_TYPES23, _STDEX_TYPES_N (24)
1093#define _STDEX_ARGS24 _STDEX_ARGS23, _STDEX_ARGS_N (24)
1094#define _STDEX_ARGS_NAMES24 _STDEX_ARGS_NAMES23, _STDEX_ARGS_NAMES_N (24)
1096#define _STDEX_LOCK_DEFINE(N) \
1097 _STDEX_TRY_LOCK(N) \
1098 _STDEX_LOCK_HELPER(N)
1100 _STDEX_LOCK_DEFINE(3)
1101 _STDEX_LOCK_DEFINE(4)
1102 _STDEX_LOCK_DEFINE(5)
1103 _STDEX_LOCK_DEFINE(6)
1104 _STDEX_LOCK_DEFINE(7)
1105 _STDEX_LOCK_DEFINE(8)
1106 _STDEX_LOCK_DEFINE(9)
1107 _STDEX_LOCK_DEFINE(10)
1108 _STDEX_LOCK_DEFINE(11)
1109 _STDEX_LOCK_DEFINE(12)
1110 _STDEX_LOCK_DEFINE(13)
1111 _STDEX_LOCK_DEFINE(14)
1112 _STDEX_LOCK_DEFINE(15)
1113 _STDEX_LOCK_DEFINE(16)
1114 _STDEX_LOCK_DEFINE(17)
1115 _STDEX_LOCK_DEFINE(18)
1116 _STDEX_LOCK_DEFINE(19)
1117 _STDEX_LOCK_DEFINE(20)
1118 _STDEX_LOCK_DEFINE(21)
1119 _STDEX_LOCK_DEFINE(22)
1120 _STDEX_LOCK_DEFINE(23)
1121 _STDEX_LOCK_DEFINE(24)
1123#undef _STDEX_TRY_LOCK
1124#undef _STDEX_LOCK_HELPER
1125#undef _STDEX_LOCK_DEFINE
1128 template <
class _Lockbl1,
class _Lockbl2>
1129 void _lock_impl(_Lockbl1 &_m1, _Lockbl2 &_m2)
1131 const unsigned int _lock_count = 2;
1132 unsigned int _lock_first = 0;
1135 switch (_lock_first)
1138 _lock_first = detail::_lock_helper(_m1, _m2);
1139 if (0 == _lock_first)
return;
1142 _lock_first = detail::_lock_helper(_m2, _m1);
1143 if (0 == _lock_first)
return;
1144 _lock_first = (_lock_first * 2) % _lock_count;
1150 template <
class _It>
1151 void _lock_impl_iterators(_It begin, _It end);
1153 template <
class _Lockbl1,
class _Lockbl2>
1154 int _try_lock_impl(_Lockbl1 &_m1, _Lockbl2 &_m2)
1156 return ((
int) detail::_try_lock(_m1, _m2)) - 1;
1159 template <
class _It>
1160 _It _try_lock_impl_iterators(_It begin, _It end);
1163 template <
class _Lockbl1,
class _Lockbl2>
1164 void lock(_Lockbl1 &_m1, _Lockbl2 &_m2)
1166 detail::_lock_impl(_m1, _m2);
1169 template <
class _Lockbl1,
class _Lockbl2>
1170 void lock(
const _Lockbl1 &_m1, _Lockbl2 &_m2)
1172 detail::_lock_impl(_m1, _m2);
1175 template <
class _Lockbl1,
class _Lockbl2>
1176 void lock(_Lockbl1 &_m1,
const _Lockbl2 &_m2)
1178 detail::_lock_impl(_m1, _m2);
1181 template <
class _Lockbl1,
class _Lockbl2>
1182 void lock(
const _Lockbl1 &_m1,
const _Lockbl2 &_m2)
1184 detail::_lock_impl(_m1, _m2);
1187 template <
class _Lockbl1, _STDEX_TYPES3>
1188 void lock(_Lockbl1 &_m1, _STDEX_ARGS3)
1190 const unsigned int _lock_count = 3;
1191 unsigned int _lock_first = 0;
1194 switch (_lock_first)
1197 _lock_first = detail::_lock_helper(_m1, _m2, _m3);
1198 if (0 == _lock_first)
return;
1201 _lock_first = detail::_lock_helper(_m2, _m3, _m1);
1202 if (0 == _lock_first)
return;
1203 _lock_first = (_lock_first * 2) % _lock_count;
1206 _lock_first = detail::_lock_helper(_m3, _m1, _m2);
1207 if (0 == _lock_first)
return;
1208 _lock_first = (_lock_first * 2) % _lock_count;
1214 template <
class _Lockbl1, _STDEX_TYPES4>
1215 void lock(_Lockbl1 &_m1, _STDEX_ARGS4)
1217 const unsigned int _lock_count = 4;
1218 unsigned int _lock_first = 0;
1221 switch (_lock_first)
1224 _lock_first = detail::_lock_helper(_m1, _m2, _m3, _m4);
1225 if (0 == _lock_first)
return;
1228 _lock_first = detail::_lock_helper(_m2, _m3, _m4, _m1);
1229 if (0 == _lock_first)
return;
1230 _lock_first = (_lock_first * 2) % _lock_count;
1233 _lock_first = detail::_lock_helper(_m3, _m4, _m1, _m2);
1234 if (0 == _lock_first)
return;
1235 _lock_first = (_lock_first * 2) % _lock_count;
1238 _lock_first = detail::_lock_helper(_m4, _m1, _m2, _m3);
1239 if (0 == _lock_first)
return;
1240 _lock_first = (_lock_first * 2) % _lock_count;
1246 template <
class _Lockbl1, _STDEX_TYPES5>
1247 void lock(_Lockbl1 &_m1, _STDEX_ARGS5)
1249 const unsigned int _lock_count = 5;
1250 unsigned int _lock_first = 0;
1253 switch (_lock_first)
1256 _lock_first = detail::_lock_helper(_m1, _m2, _m3, _m4, _m5);
1257 if (0 == _lock_first)
return;
1260 _lock_first = detail::_lock_helper(_m2, _m3, _m4, _m5, _m1);
1261 if (0 == _lock_first)
return;
1262 _lock_first = (_lock_first * 2) % _lock_count;
1265 _lock_first = detail::_lock_helper(_m3, _m4, _m5, _m1, _m2);
1266 if (0 == _lock_first)
return;
1267 _lock_first = (_lock_first * 2) % _lock_count;
1270 _lock_first = detail::_lock_helper(_m4, _m5, _m1, _m2, _m3);
1271 if (0 == _lock_first)
return;
1272 _lock_first = (_lock_first * 2) % _lock_count;
1275 _lock_first = detail::_lock_helper(_m5, _m1, _m2, _m3, _m4);
1276 if (0 == _lock_first)
return;
1277 _lock_first = (_lock_first * 2) % _lock_count;
1283 template <
class _Lockbl1, _STDEX_TYPES6>
1284 void lock(_Lockbl1 &_m1, _STDEX_ARGS6)
1286 const unsigned int _lock_count = 6;
1287 unsigned int _lock_first = 0;
1290 switch (_lock_first)
1293 _lock_first = detail::_lock_helper(_m1, _m2, _m3, _m4, _m5, _m6);
1294 if (0 == _lock_first)
return;
1297 _lock_first = detail::_lock_helper(_m2, _m3, _m4, _m5, _m6, _m1);
1298 if (0 == _lock_first)
return;
1299 _lock_first = (_lock_first * 2) % _lock_count;
1302 _lock_first = detail::_lock_helper(_m3, _m4, _m5, _m6, _m1, _m2);
1303 if (0 == _lock_first)
return;
1304 _lock_first = (_lock_first * 2) % _lock_count;
1307 _lock_first = detail::_lock_helper(_m4, _m5, _m6, _m1, _m2, _m3);
1308 if (0 == _lock_first)
return;
1309 _lock_first = (_lock_first * 2) % _lock_count;
1312 _lock_first = detail::_lock_helper(_m5, _m6, _m1, _m2, _m3, _m4);
1313 if (0 == _lock_first)
return;
1314 _lock_first = (_lock_first * 2) % _lock_count;
1317 _lock_first = detail::_lock_helper(_m6, _m1, _m2, _m3, _m4, _m5);
1318 if (0 == _lock_first)
return;
1319 _lock_first = (_lock_first * 2) % _lock_count;
1325 template <
class _Lockbl1, _STDEX_TYPES7>
1326 void lock(_Lockbl1 &_m1, _STDEX_ARGS7)
1328 const unsigned int _lock_count = 7;
1329 unsigned int _lock_first = 0;
1332 switch (_lock_first)
1335 _lock_first = detail::_lock_helper(_m1, _m2, _m3, _m4, _m5, _m6, _m7);
1336 if (0 == _lock_first)
return;
1339 _lock_first = detail::_lock_helper(_m2, _m3, _m4, _m5, _m6, _m7, _m1);
1340 if (0 == _lock_first)
return;
1341 _lock_first = (_lock_first * 2) % _lock_count;
1344 _lock_first = detail::_lock_helper(_m3, _m4, _m5, _m6, _m7, _m1, _m2);
1345 if (0 == _lock_first)
return;
1346 _lock_first = (_lock_first * 2) % _lock_count;
1349 _lock_first = detail::_lock_helper(_m4, _m5, _m6, _m7, _m1, _m2, _m3);
1350 if (0 == _lock_first)
return;
1351 _lock_first = (_lock_first * 2) % _lock_count;
1354 _lock_first = detail::_lock_helper(_m5, _m6, _m7, _m1, _m2, _m3, _m4);
1355 if (0 == _lock_first)
return;
1356 _lock_first = (_lock_first * 2) % _lock_count;
1359 _lock_first = detail::_lock_helper(_m6, _m7, _m1, _m2, _m3, _m4, _m5);
1360 if (0 == _lock_first)
return;
1361 _lock_first = (_lock_first * 2) % _lock_count;
1364 _lock_first = detail::_lock_helper(_m7, _m1, _m2, _m3, _m4, _m5, _m6);
1365 if (0 == _lock_first)
return;
1366 _lock_first = (_lock_first * 2) % _lock_count;
1372 template <
class _Lockbl1, _STDEX_TYPES8>
1373 void lock(_Lockbl1 &_m1, _STDEX_ARGS8)
1375 const unsigned int _lock_count = 8;
1376 unsigned int _lock_first = 0;
1379 switch (_lock_first)
1382 _lock_first = detail::_lock_helper(_m1, _m2, _m3, _m4, _m5, _m6, _m7, _m8);
1383 if (0 == _lock_first)
return;
1386 _lock_first = detail::_lock_helper(_m2, _m3, _m4, _m5, _m6, _m7, _m8, _m1);
1387 if (0 == _lock_first)
return;
1388 _lock_first = (_lock_first * 2) % _lock_count;
1391 _lock_first = detail::_lock_helper(_m3, _m4, _m5, _m6, _m7, _m8, _m1, _m2);
1392 if (0 == _lock_first)
return;
1393 _lock_first = (_lock_first * 2) % _lock_count;
1396 _lock_first = detail::_lock_helper(_m4, _m5, _m6, _m7, _m8, _m1, _m2, _m3);
1397 if (0 == _lock_first)
return;
1398 _lock_first = (_lock_first * 2) % _lock_count;
1401 _lock_first = detail::_lock_helper(_m5, _m6, _m7, _m8, _m1, _m2, _m3, _m4);
1402 if (0 == _lock_first)
return;
1403 _lock_first = (_lock_first * 2) % _lock_count;
1406 _lock_first = detail::_lock_helper(_m6, _m7, _m8, _m1, _m2, _m3, _m4, _m5);
1407 if (0 == _lock_first)
return;
1408 _lock_first = (_lock_first * 2) % _lock_count;
1411 _lock_first = detail::_lock_helper(_m7, _m8, _m1, _m2, _m3, _m4, _m5, _m6);
1412 if (0 == _lock_first)
return;
1413 _lock_first = (_lock_first * 2) % _lock_count;
1416 _lock_first = detail::_lock_helper(_m8, _m1, _m2, _m3, _m4, _m5, _m6, _m7);
1417 if (0 == _lock_first)
return;
1418 _lock_first = (_lock_first * 2) % _lock_count;
1424 template <
class _Lockbl1,
class _Lockbl2>
1425 int try_lock(_Lockbl1 &_m1, _Lockbl2 &_m2)
1427 return detail::_try_lock_impl(_m1, _m2);
1430 template <
class _Lockbl1,
class _Lockbl2>
1431 int try_lock(
const _Lockbl1 &_m1, _Lockbl2 &_m2)
1433 return detail::_try_lock_impl(_m1, _m2);
1436 template <
class _Lockbl1,
class _Lockbl2>
1437 int try_lock(_Lockbl1 &_m1,
const _Lockbl2 &_m2)
1439 return detail::_try_lock_impl(_m1, _m2);
1442 template <
class _Lockbl1,
class _Lockbl2>
1443 int try_lock(
const _Lockbl1 &_m1,
const _Lockbl2 &_m2)
1445 return detail::_try_lock_impl(_m1, _m2);
1448 using detail::try_lock;
1450#undef _STDEX_TYPES_N
1452#undef _STDEX_ARGS_NAMES_N
1456#undef _STDEX_ARGS_NAMES3
1459#undef _STDEX_ARGS_NAMES4
1462#undef _STDEX_ARGS_NAMES5
1465#undef _STDEX_ARGS_NAMES6
1468#undef _STDEX_ARGS_NAMES7
1471#undef _STDEX_ARGS_NAMES8
1474#undef _STDEX_ARGS_NAMES9
1475#undef _STDEX_TYPES10
1477#undef _STDEX_ARGS_NAMES10
1478#undef _STDEX_TYPES11
1480#undef _STDEX_ARGS_NAMES11
1481#undef _STDEX_TYPES12
1483#undef _STDEX_ARGS_NAMES12
1484#undef _STDEX_TYPES13
1486#undef _STDEX_ARGS_NAMES13
1487#undef _STDEX_TYPES14
1489#undef _STDEX_ARGS_NAMES14
1490#undef _STDEX_TYPES15
1492#undef _STDEX_ARGS_NAMES15
1493#undef _STDEX_TYPES16
1495#undef _STDEX_ARGS_NAMES16
1496#undef _STDEX_TYPES17
1498#undef _STDEX_ARGS_NAMES17
1499#undef _STDEX_TYPES18
1501#undef _STDEX_ARGS_NAMES18
1502#undef _STDEX_TYPES19
1504#undef _STDEX_ARGS_NAMES19
1505#undef _STDEX_TYPES20
1507#undef _STDEX_ARGS_NAMES20
1508#undef _STDEX_TYPES21
1510#undef _STDEX_ARGS_NAMES21
1511#undef _STDEX_TYPES22
1513#undef _STDEX_ARGS_NAMES22
1514#undef _STDEX_TYPES23
1516#undef _STDEX_ARGS_NAMES23
1517#undef _STDEX_TYPES24
1519#undef _STDEX_ARGS_NAMES24
1522#undef _STDEX_DELETED_FUNCTION
1523#undef _STDEX_NOEXCEPT_FUNCTION
1524#undef _STDEX_NOEXCEPT
thread::id get_id()
Return the thread ID of the calling thread.