winmutex.h
4.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#pragma once
// winmutex.h
// 12/11/2011 jichi
#include <windows.h>
#ifdef _MSC_VER
# pragma warning(disable:4800) // C4800: forcing value to bool
#endif // _MSC_VER
// Mutex lock
// The interface of this class is consistent with the mutex class
template <typename _Mutex>
class win_mutex_lock
{
typedef win_mutex_lock<_Mutex> _Self;
win_mutex_lock(const _Self&);
_Self &operator=(const _Self&);
_Mutex &_M_mutex;
bool _M_locked;
public:
typedef _Mutex mutex_type;
typedef typename _Mutex::native_handle_type native_handle_type;
explicit win_mutex_lock(mutex_type &mutex)
: _M_mutex(mutex), _M_locked(false) { lock(); }
~win_mutex_lock() { if (_M_locked) _M_mutex.unlock(); }
mutex_type &mutex() { return _M_mutex; }
//bool isLock() const { return _M_locked; }
native_handle_type native_handle() { return _M_mutex.native_handle(); }
void unlock() { _M_mutex.unlock(); _M_locked = false; }
void lock() { _M_mutex.lock(); _M_locked = true; }
bool tryLock() { return _M_locked = _M_mutex.tryLock(); }
};
// Mutex
template <typename _Mutex, size_t _Irql = 0>
class win_mutex
{
typedef win_mutex<_Mutex> _Self;
typedef _Mutex __native_type;
enum { __minimal_irql = _Irql };
__native_type _M_mutex;
win_mutex(const _Self&);
_Self &operator=(const _Self&);
private:
win_mutex() {}
typedef __native_type *native_handle_type;
native_handle_type native_handle() { return &_M_mutex; }
static size_t minimal_irql() { return __minimal_irql; }
void unlock() {}
void lock() {}
bool try_lock() {}
};
template <>
class IHFSERVICE win_mutex<CRITICAL_SECTION>
{
typedef win_mutex<CRITICAL_SECTION> _Self;
typedef CRITICAL_SECTION __native_type;
enum { __minimal_irql = 0 };
win_mutex(const _Self&);
_Self &operator=(const _Self&);
__native_type _M_mutex;
public:
typedef __native_type *native_handle_type;
native_handle_type native_handle() { return &_M_mutex; }
static size_t minimal_irql() { return __minimal_irql; }
win_mutex() { ::InitializeCriticalSection(&_M_mutex); }
~win_mutex() { ::DeleteCriticalSection(&_M_mutex); }
void lock() { ::EnterCriticalSection(&_M_mutex); }
void unlock() { ::LeaveCriticalSection(&_M_mutex); }
bool try_lock() { return ::TryEnterCriticalSection(&_M_mutex); }
};
// Conditional variable
template <typename _Cond>
class win_mutex_cond
{
typedef win_mutex_cond<_Cond> _Self;
typedef _Cond __native_type;
win_mutex_cond(const _Self&);
_Self &operator=(const _Self&);
__native_type _M_cond;
public:
enum wait_status { no_timeout = 0, timeout };
typedef __native_type *native_handle_type;
win_mutex_cond() {}
native_handle_type native_handle() { return &_M_cond; }
void notify_one() {}
void notify_all() {}
template <typename _Mutex>
void wait(_Mutex &mutex) {}
template <typename _Mutex, typename _Pred>
void wait(_Mutex &mutex, _Pred pred) {}
template <typename _Mutex>
wait_status wait_for(_Mutex &mutex, int msecs) {}
template <typename _Mutex, typename _Pred>
wait_status wait_for(_Mutex &mutex, int msecs, _Pred pred) {}
};
// Note: Conditional variables are NOT availabe on Windows XP/2003
// See: http://en.cppreference.com/w/cpp/thread/condition_variable
// See: http://msdn.microsoft.com/en-us/library/windows/desktop/ms686903%28v=vs.85%29.aspx
template <>
class win_mutex_cond<CONDITION_VARIABLE>
{
typedef win_mutex_cond<CONDITION_VARIABLE> _Self;
typedef CONDITION_VARIABLE __native_type;
win_mutex_cond(const _Self&);
_Self &operator=(const _Self&);
__native_type _M_cond;
public:
enum wait_status { no_timeout = 0, timeout };
typedef __native_type *native_handle_type;
native_handle_type native_handle() { return &_M_cond; }
win_mutex_cond() { ::InitializeConditionVariable(&_M_cond); }
void notify_one() { ::WakeConditionVariable(&_M_cond); }
void notify_all() { ::WakeAllConditionVariable(&_M_cond); }
template <typename _Mutex>
void wait(_Mutex &mutex)
{ ::SleepConditionVariableCS(&_M_cond, mutex.native_handle(), INFINITE); }
template <typename _Mutex, typename _Pred>
void wait(_Mutex &mutex, _Pred pred)
{ while (!pred()) wait(mutex); }
template <typename _Mutex>
wait_status wait_for(_Mutex &mutex, int msecs)
{ return ::SleepConditionVariableCS(&_M_cond, mutex.native_handle(), msecs) ? no_timeout : timeout; }
template <typename _Mutex, typename _Pred>
wait_status wait_for(_Mutex &mutex, int msecs, _Pred pred)
{
auto start = ::GetTickCount();
while (!pred()) {
auto now = ::GetTickCount();
msecs -= now - start;
if (msecs <= 0)
return timeout;
start = now;
wait_for(mutex, msecs);
}
return no_timeout;
}
};
// EOF