1 //  synchronizaion.hpp  --------------------------------------------------------------//
2 
3 //  Copyright 2010 Vicente J. Botet Escriba
4 
5 //  Distributed under the Boost Software License, Version 1.0.
6 //  See http://www.boost.org/LICENSE_1_0.txt
7 
8 
9 #ifndef BOOST_DETAIL_WINAPI_SYNCHRONIZATION_HPP
10 #define BOOST_DETAIL_WINAPI_SYNCHRONIZATION_HPP
11 
12 #include <boost/detail/winapi/basic_types.hpp>
13 
14 #ifdef BOOST_HAS_PRAGMA_ONCE
15 #pragma once
16 #endif
17 
18 namespace boost
19 {
20 namespace detail
21 {
22 namespace winapi
23 {
24 #if defined( BOOST_USE_WINDOWS_H )
25     typedef ::CRITICAL_SECTION CRITICAL_SECTION_;
26     typedef ::PAPCFUNC PAPCFUNC_;
27 
28 #if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
29     typedef ::INIT_ONCE INIT_ONCE_;
30     typedef ::PINIT_ONCE PINIT_ONCE_;
31     typedef ::LPINIT_ONCE LPINIT_ONCE_;
32     #define BOOST_DETAIL_WINAPI_INIT_ONCE_STATIC_INIT INIT_ONCE_STATIC_INIT
33     typedef ::PINIT_ONCE_FN PINIT_ONCE_FN_;
34 
35     typedef ::SRWLOCK SRWLOCK_;
36     typedef ::PSRWLOCK PSRWLOCK_;
37     #define BOOST_DETAIL_WINAPI_SRWLOCK_INIT SRWLOCK_INIT
38 
39     typedef ::CONDITION_VARIABLE CONDITION_VARIABLE_;
40     typedef ::PCONDITION_VARIABLE PCONDITION_VARIABLE_;
41     #define BOOST_DETAIL_WINAPI_CONDITION_VARIABLE_INIT CONDITION_VARIABLE_INIT
42 #endif
43 
44     using ::InitializeCriticalSection;
45 #if BOOST_USE_WINAPI_VERSION >= 0x0403
46     using ::InitializeCriticalSectionAndSpinCount;
47 #endif
48     using ::EnterCriticalSection;
49     using ::TryEnterCriticalSection;
50     using ::LeaveCriticalSection;
51     using ::DeleteCriticalSection;
52 
53 # ifdef BOOST_NO_ANSI_APIS
54     using ::CreateMutexW;
55     using ::OpenMutexW;
56     using ::CreateEventW;
57     using ::OpenEventW;
58     using ::CreateSemaphoreW;
59     using ::OpenSemaphoreW;
60 # else
61     using ::CreateMutexA;
62     using ::OpenMutexA;
63     using ::CreateEventA;
64     using ::OpenEventA;
65     using ::CreateSemaphoreA;
66     using ::OpenSemaphoreA;
67 # endif
68     using ::ReleaseMutex;
69     using ::ReleaseSemaphore;
70     using ::SetEvent;
71     using ::ResetEvent;
72     using ::WaitForMultipleObjects;
73     using ::WaitForSingleObject;
74     using ::QueueUserAPC;
75 
76 #if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
77     using ::InitOnceInitialize;
78     using ::InitOnceExecuteOnce;
79     using ::InitOnceBeginInitialize;
80     using ::InitOnceComplete;
81 
82     using ::InitializeSRWLock;
83     using ::AcquireSRWLockExclusive;
84     using ::TryAcquireSRWLockExclusive;
85     using ::ReleaseSRWLockExclusive;
86     using ::AcquireSRWLockShared;
87     using ::TryAcquireSRWLockShared;
88     using ::ReleaseSRWLockShared;
89 
90     using ::InitializeConditionVariable;
91     using ::WakeConditionVariable;
92     using ::WakeAllConditionVariable;
93     using ::SleepConditionVariableCS;
94     using ::SleepConditionVariableSRW;
95 #endif
96 
97     const DWORD_ infinite       = INFINITE;
98     const DWORD_ wait_abandoned = WAIT_ABANDONED;
99     const DWORD_ wait_object_0  = WAIT_OBJECT_0;
100     const DWORD_ wait_timeout   = WAIT_TIMEOUT;
101     const DWORD_ wait_failed    = WAIT_FAILED;
102 
103 #if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
104     const DWORD_ init_once_async = INIT_ONCE_ASYNC;
105     const DWORD_ init_once_check_only = INIT_ONCE_CHECK_ONLY;
106     const DWORD_ init_once_init_failed = INIT_ONCE_INIT_FAILED;
107     const DWORD_ init_once_ctx_reserved_bits = INIT_ONCE_CTX_RESERVED_BITS;
108 
109     const ULONG_ condition_variable_lockmode_shared = CONDITION_VARIABLE_LOCKMODE_SHARED;
110 #endif
111 
112 #else // defined( BOOST_USE_WINDOWS_H )
113 
114 extern "C" {
115 
116     typedef struct CRITICAL_SECTION_
117     {
118         struct critical_section_debug * DebugInfo;
119         long LockCount;
120         long RecursionCount;
121         void * OwningThread;
122         void * LockSemaphore;
123     #if defined(_WIN64)
124         unsigned __int64 SpinCount;
125     #else
126         unsigned long SpinCount;
127     #endif
128     }
129     *PCRITICAL_SECTION_;
130 
131 #if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
132     typedef union INIT_ONCE_
133     {
134         PVOID_ Ptr;
135     }
136     *PINIT_ONCE_, *LPINIT_ONCE_;
137     #define BOOST_DETAIL_WINAPI_INIT_ONCE_STATIC_INIT {0}
138     typedef BOOL_ (WINAPI *PINIT_ONCE_FN_)(PINIT_ONCE_ InitOnce, PVOID_ Parameter, PVOID_ *Context);
139 
140     typedef struct SRWLOCK_
141     {
142         PVOID_ Ptr;
143     }
144     * PSRWLOCK_;
145     #define BOOST_DETAIL_WINAPI_SRWLOCK_INIT {0}
146 
147     typedef struct CONDITION_VARIABLE_
148     {
149         PVOID_ Ptr;
150     }
151     * PCONDITION_VARIABLE_;
152     #define BOOST_DETAIL_WINAPI_CONDITION_VARIABLE_INIT {0}
153 
154 #endif
155 
156     __declspec(dllimport) void WINAPI
157         InitializeCriticalSection(PCRITICAL_SECTION_);
158 #if BOOST_USE_WINAPI_VERSION >= 0x0403
159     __declspec(dllimport) BOOL_ WINAPI
160         InitializeCriticalSectionAndSpinCount(CRITICAL_SECTION_* lpCS, DWORD_ dwSpinCount);
161 #endif
162     __declspec(dllimport) void WINAPI
163         EnterCriticalSection(PCRITICAL_SECTION_);
164     __declspec(dllimport) BOOL_ WINAPI
165         TryEnterCriticalSection(PCRITICAL_SECTION_);
166     __declspec(dllimport) void WINAPI
167         LeaveCriticalSection(PCRITICAL_SECTION_);
168     __declspec(dllimport) void WINAPI
169         DeleteCriticalSection(PCRITICAL_SECTION_);
170 
171      struct _SECURITY_ATTRIBUTES;
172 # ifdef BOOST_NO_ANSI_APIS
173     __declspec(dllimport) HANDLE_ WINAPI
174         CreateMutexW(_SECURITY_ATTRIBUTES*, BOOL_, LPCWSTR_);
175     __declspec(dllimport) HANDLE_ WINAPI
176         OpenMutexW(DWORD_ dwDesiredAccess, BOOL_ bInheritHandle, LPCWSTR_ lpName);
177     __declspec(dllimport) HANDLE_ WINAPI
178         CreateSemaphoreW(_SECURITY_ATTRIBUTES*, LONG_, LONG_, LPCWSTR_);
179     __declspec(dllimport) HANDLE_ WINAPI
180         OpenSemaphoreW(DWORD_ dwDesiredAccess, BOOL_ bInheritHandle, LPCWSTR_ lpName);
181     __declspec(dllimport) HANDLE_ WINAPI
182         CreateEventW(_SECURITY_ATTRIBUTES*, BOOL_, BOOL_, LPCWSTR_);
183     __declspec(dllimport) HANDLE_ WINAPI
184         OpenEventW(DWORD_, BOOL_, LPCWSTR_);
185 # else
186     __declspec(dllimport) HANDLE_ WINAPI
187         CreateMutexA(_SECURITY_ATTRIBUTES*, BOOL_, LPCSTR_);
188     __declspec(dllimport) HANDLE_ WINAPI
189         OpenMutexA(DWORD_ dwDesiredAccess, BOOL_ bInheritHandle, LPCSTR_ lpName);
190     __declspec(dllimport) HANDLE_ WINAPI
191         CreateSemaphoreA(_SECURITY_ATTRIBUTES*, LONG_, LONG_, LPCSTR_);
192     __declspec(dllimport) HANDLE_ WINAPI
193         OpenSemaphoreA(DWORD_ dwDesiredAccess, BOOL_ bInheritHandle, LPCSTR_ lpName);
194     __declspec(dllimport) HANDLE_ WINAPI
195         CreateEventA(_SECURITY_ATTRIBUTES*, BOOL_, BOOL_, LPCSTR_);
196     __declspec(dllimport) HANDLE_ WINAPI
197         OpenEventA(DWORD_, BOOL_, LPCSTR_);
198 # endif
199     __declspec(dllimport) BOOL_ WINAPI
200         ReleaseMutex(HANDLE_);
201     __declspec(dllimport) DWORD_ WINAPI
202         WaitForSingleObject(HANDLE_, DWORD_);
203     __declspec(dllimport) DWORD_ WINAPI
204         WaitForMultipleObjects(DWORD_ nCount,
205                 HANDLE_ const * lpHandles,
206                 BOOL_ bWaitAll,
207                 DWORD_ dwMilliseconds);
208     __declspec(dllimport) BOOL_ WINAPI
209         ReleaseSemaphore(HANDLE_, LONG_, LONG_*);
210     __declspec(dllimport) BOOL_ WINAPI
211         SetEvent(HANDLE_);
212     __declspec(dllimport) BOOL_ WINAPI
213         ResetEvent(HANDLE_);
214 
215     typedef void (__stdcall *PAPCFUNC_)(ULONG_PTR_);
216     __declspec(dllimport) DWORD_ WINAPI
217         QueueUserAPC(PAPCFUNC_, HANDLE_, ULONG_PTR_);
218 
219 #if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
220     __declspec(dllimport) void WINAPI InitOnceInitialize(PINIT_ONCE_);
221     __declspec(dllimport) BOOL_ WINAPI InitOnceExecuteOnce(PINIT_ONCE_ InitOnce, PINIT_ONCE_FN_ InitFn, PVOID_ Parameter, LPVOID_* Context);
222     __declspec(dllimport) BOOL_ WINAPI InitOnceBeginInitialize(LPINIT_ONCE_ lpInitOnce, DWORD_ dwFlags, BOOL_* fPending, LPVOID_* lpContext);
223     __declspec(dllimport) BOOL_ WINAPI InitOnceComplete(LPINIT_ONCE_ lpInitOnce, DWORD_ dwFlags, LPVOID_* lpContext);
224 
225 
226     __declspec(dllimport) void WINAPI InitializeSRWLock(PSRWLOCK_ SRWLock);
227     __declspec(dllimport) void WINAPI AcquireSRWLockExclusive(PSRWLOCK_ SRWLock);
228     __declspec(dllimport) BOOLEAN_ WINAPI TryAcquireSRWLockExclusive(PSRWLOCK_ SRWLock);
229     __declspec(dllimport) void WINAPI ReleaseSRWLockExclusive(PSRWLOCK_ SRWLock);
230     __declspec(dllimport) void WINAPI AcquireSRWLockShared(PSRWLOCK_ SRWLock);
231     __declspec(dllimport) BOOLEAN_ WINAPI TryAcquireSRWLockShared(PSRWLOCK_ SRWLock);
232     __declspec(dllimport) void WINAPI ReleaseSRWLockShared(PSRWLOCK_ SRWLock);
233 
234     __declspec(dllimport) void WINAPI InitializeConditionVariable(PCONDITION_VARIABLE_ ConditionVariable);
235     __declspec(dllimport) void WINAPI WakeConditionVariable(PCONDITION_VARIABLE_ ConditionVariable);
236     __declspec(dllimport) void WINAPI WakeAllConditionVariable(PCONDITION_VARIABLE_ ConditionVariable);
237     __declspec(dllimport) BOOL_ WINAPI SleepConditionVariableCS(PCONDITION_VARIABLE_ ConditionVariable, PCRITICAL_SECTION_ CriticalSection, DWORD_ dwMilliseconds);
238     __declspec(dllimport) BOOL_ WINAPI SleepConditionVariableSRW(PCONDITION_VARIABLE_ ConditionVariable, PSRWLOCK_ SRWLock, DWORD_ dwMilliseconds, ULONG_ Flags);
239 #endif
240 
241 } // extern "C"
242 
243 const DWORD_ infinite       = (DWORD_)0xFFFFFFFF;
244 const DWORD_ wait_abandoned = 0x00000080L;
245 const DWORD_ wait_object_0  = 0x00000000L;
246 const DWORD_ wait_timeout   = 0x00000102L;
247 const DWORD_ wait_failed    = (DWORD_)0xFFFFFFFF;
248 
249 #if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6
250 const DWORD_ init_once_async = 0x00000002UL;
251 const DWORD_ init_once_check_only = 0x00000001UL;
252 const DWORD_ init_once_init_failed = 0x00000004UL;
253 const DWORD_ init_once_ctx_reserved_bits = 2;
254 
255 const ULONG_ condition_variable_lockmode_shared = 0x00000001;
256 #endif
257 
258 #endif // defined( BOOST_USE_WINDOWS_H )
259 
260 const DWORD_ max_non_infinite_wait = (DWORD_)0xFFFFFFFE;
261 
create_anonymous_mutex(_SECURITY_ATTRIBUTES * lpAttributes,BOOL_ bInitialOwner)262 BOOST_FORCEINLINE HANDLE_ create_anonymous_mutex(_SECURITY_ATTRIBUTES* lpAttributes, BOOL_ bInitialOwner)
263 {
264 #ifdef BOOST_NO_ANSI_APIS
265     return CreateMutexW(lpAttributes, bInitialOwner, 0);
266 #else
267     return CreateMutexA(lpAttributes, bInitialOwner, 0);
268 #endif
269 }
270 
create_anonymous_semaphore(_SECURITY_ATTRIBUTES * lpAttributes,LONG_ lInitialCount,LONG_ lMaximumCount)271 BOOST_FORCEINLINE HANDLE_ create_anonymous_semaphore(_SECURITY_ATTRIBUTES* lpAttributes, LONG_ lInitialCount, LONG_ lMaximumCount)
272 {
273 #ifdef BOOST_NO_ANSI_APIS
274     return CreateSemaphoreW(lpAttributes, lInitialCount, lMaximumCount, 0);
275 #else
276     return CreateSemaphoreA(lpAttributes, lInitialCount, lMaximumCount, 0);
277 #endif
278 }
279 
create_anonymous_event(_SECURITY_ATTRIBUTES * lpAttributes,BOOL_ bManualReset,BOOL_ bInitialState)280 BOOST_FORCEINLINE HANDLE_ create_anonymous_event(_SECURITY_ATTRIBUTES* lpAttributes, BOOL_ bManualReset, BOOL_ bInitialState)
281 {
282 #ifdef BOOST_NO_ANSI_APIS
283     return CreateEventW(lpAttributes, bManualReset, bInitialState, 0);
284 #else
285     return CreateEventA(lpAttributes, bManualReset, bInitialState, 0);
286 #endif
287 }
288 
289 }
290 }
291 }
292 
293 #endif // BOOST_DETAIL_WINAPI_SYNCHRONIZATION_HPP
294