1 #ifndef BOOST_WIN32_THREAD_PRIMITIVES_HPP
2 #define BOOST_WIN32_THREAD_PRIMITIVES_HPP
4 // win32_thread_primitives.hpp
6 // (C) Copyright 2005-7 Anthony Williams
7 // (C) Copyright 2007 David Deakins
9 // Distributed under the Boost Software License, Version 1.0. (See
10 // accompanying file LICENSE_1_0.txt or copy at
11 // http://www.boost.org/LICENSE_1_0.txt)
13 #include <boost/config.hpp>
14 #include <boost/assert.hpp>
15 #include <boost/thread/exceptions.hpp>
16 #include <boost/detail/interlocked.hpp>
19 #if defined( BOOST_USE_WINDOWS_H )
28 typedef ULONG_PTR ulong_ptr
;
29 typedef HANDLE handle
;
30 unsigned const infinite
=INFINITE
;
31 unsigned const timeout
=WAIT_TIMEOUT
;
32 handle
const invalid_handle_value
=INVALID_HANDLE_VALUE
;
34 # ifdef BOOST_NO_ANSI_APIS
37 using ::CreateSemaphoreW
;
41 using ::CreateSemaphoreA
;
45 using ::ReleaseSemaphore
;
48 using ::WaitForMultipleObjects
;
49 using ::WaitForSingleObject
;
50 using ::GetCurrentProcessId
;
51 using ::GetCurrentThreadId
;
52 using ::GetCurrentThread
;
53 using ::GetCurrentProcess
;
54 using ::DuplicateHandle
;
62 #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
66 # ifndef _WIN32_WCE_EMULATION
67 # define WINAPI __cdecl // Note this doesn't match the desktop definition
69 # define WINAPI __stdcall
77 typedef unsigned long DWORD
;
94 typedef unsigned __int64 ulong_ptr
;
96 typedef unsigned long ulong_ptr
;
99 unsigned const infinite
=~0U;
100 unsigned const timeout
=258U;
101 handle
const invalid_handle_value
=(handle
)(-1);
105 struct _SECURITY_ATTRIBUTES
;
106 # ifdef BOOST_NO_ANSI_APIS
107 __declspec(dllimport
) void* __stdcall
CreateMutexW(_SECURITY_ATTRIBUTES
*,int,wchar_t const*);
108 __declspec(dllimport
) void* __stdcall
CreateSemaphoreW(_SECURITY_ATTRIBUTES
*,long,long,wchar_t const*);
109 __declspec(dllimport
) void* __stdcall
CreateEventW(_SECURITY_ATTRIBUTES
*,int,int,wchar_t const*);
111 __declspec(dllimport
) void* __stdcall
CreateMutexA(_SECURITY_ATTRIBUTES
*,int,char const*);
112 __declspec(dllimport
) void* __stdcall
CreateSemaphoreA(_SECURITY_ATTRIBUTES
*,long,long,char const*);
113 __declspec(dllimport
) void* __stdcall
CreateEventA(_SECURITY_ATTRIBUTES
*,int,int,char const*);
115 __declspec(dllimport
) int __stdcall
CloseHandle(void*);
116 __declspec(dllimport
) int __stdcall
ReleaseMutex(void*);
117 __declspec(dllimport
) unsigned long __stdcall
WaitForSingleObject(void*,unsigned long);
118 __declspec(dllimport
) unsigned long __stdcall
WaitForMultipleObjects(unsigned long nCount
,void* const * lpHandles
,int bWaitAll
,unsigned long dwMilliseconds
);
119 __declspec(dllimport
) int __stdcall
ReleaseSemaphore(void*,long,long*);
120 __declspec(dllimport
) int __stdcall
DuplicateHandle(void*,void*,void*,void**,unsigned long,int,unsigned long);
121 __declspec(dllimport
) unsigned long __stdcall
SleepEx(unsigned long,int);
122 __declspec(dllimport
) void __stdcall
Sleep(unsigned long);
123 typedef void (__stdcall
*queue_user_apc_callback_function
)(ulong_ptr
);
124 __declspec(dllimport
) unsigned long __stdcall
QueueUserAPC(queue_user_apc_callback_function
,void*,ulong_ptr
);
126 __declspec(dllimport
) unsigned long __stdcall
GetTickCount();
129 __declspec(dllimport
) unsigned long __stdcall
GetCurrentProcessId();
130 __declspec(dllimport
) unsigned long __stdcall
GetCurrentThreadId();
131 __declspec(dllimport
) void* __stdcall
GetCurrentThread();
132 __declspec(dllimport
) void* __stdcall
GetCurrentProcess();
133 __declspec(dllimport
) int __stdcall
SetEvent(void*);
134 __declspec(dllimport
) int __stdcall
ResetEvent(void*);
136 using ::GetCurrentProcessId
;
137 using ::GetCurrentThreadId
;
138 using ::GetCurrentThread
;
139 using ::GetCurrentProcess
;
148 # error "Win32 functions not available"
151 #include <boost/config/abi_prefix.hpp>
161 auto_reset_event
=false,
162 manual_reset_event
=true
165 enum initial_event_state
167 event_initially_reset
=false,
168 event_initially_set
=true
171 inline handle
create_anonymous_event(event_type type
,initial_event_state state
)
173 #if !defined(BOOST_NO_ANSI_APIS)
174 handle
const res
=win32::CreateEventA(0,type
,state
,0);
176 handle
const res
=win32::CreateEventW(0,type
,state
,0);
180 throw thread_resource_error();
185 inline handle
create_anonymous_semaphore(long initial_count
,long max_count
)
187 #if !defined(BOOST_NO_ANSI_APIS)
188 handle
const res
=CreateSemaphoreA(0,initial_count
,max_count
,0);
190 handle
const res
=CreateSemaphoreW(0,initial_count
,max_count
,0);
194 throw thread_resource_error();
199 inline handle
duplicate_handle(handle source
)
201 handle
const current_process
=GetCurrentProcess();
202 long const same_access_flag
=2;
204 bool const success
=DuplicateHandle(current_process
,source
,current_process
,&new_handle
,0,false,same_access_flag
)!=0;
207 throw thread_resource_error();
212 inline void release_semaphore(handle semaphore
,long count
)
214 BOOST_VERIFY(ReleaseSemaphore(semaphore
,count
,0)!=0);
220 handle handle_to_manage
;
221 handle_manager(handle_manager
&);
222 handle_manager
& operator=(handle_manager
&);
226 if(handle_to_manage
&& handle_to_manage
!=invalid_handle_value
)
228 BOOST_VERIFY(CloseHandle(handle_to_manage
));
233 explicit handle_manager(handle handle_to_manage_
):
234 handle_to_manage(handle_to_manage_
)
240 handle_manager
& operator=(handle new_handle
)
243 handle_to_manage
=new_handle
;
247 operator handle() const
249 return handle_to_manage
;
252 handle
duplicate() const
254 return duplicate_handle(handle_to_manage
);
257 void swap(handle_manager
& other
)
259 std::swap(handle_to_manage
,other
.handle_to_manage
);
264 handle
const res
=handle_to_manage
;
269 bool operator!() const
271 return !handle_to_manage
;
284 #if defined(BOOST_MSVC) && (_MSC_VER>=1400) && !defined(UNDER_CE)
293 extern "C" unsigned char _interlockedbittestandset(long *a
,long b
);
294 extern "C" unsigned char _interlockedbittestandreset(long *a
,long b
);
296 extern "C" unsigned char _interlockedbittestandset(volatile long *a
,long b
);
297 extern "C" unsigned char _interlockedbittestandreset(volatile long *a
,long b
);
300 #pragma intrinsic(_interlockedbittestandset)
301 #pragma intrinsic(_interlockedbittestandreset)
303 inline bool interlocked_bit_test_and_set(long* x
,long bit
)
305 return _interlockedbittestandset(x
,bit
)!=0;
308 inline bool interlocked_bit_test_and_reset(long* x
,long bit
)
310 return _interlockedbittestandreset(x
,bit
)!=0;
316 #define BOOST_THREAD_BTS_DEFINED
317 #elif (defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)) && defined(_M_IX86)
324 inline bool interlocked_bit_test_and_set(long* x
,long bit
)
334 inline bool interlocked_bit_test_and_reset(long* x
,long bit
)
347 #define BOOST_THREAD_BTS_DEFINED
350 #ifndef BOOST_THREAD_BTS_DEFINED
358 inline bool interlocked_bit_test_and_set(long* x
,long bit
)
360 long const value
=1<<bit
;
364 long const current
=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x
,old
|value
,old
);
372 return (old
&value
)!=0;
375 inline bool interlocked_bit_test_and_reset(long* x
,long bit
)
377 long const value
=1<<bit
;
381 long const current
=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x
,old
&~value
,old
);
389 return (old
&value
)!=0;
396 #include <boost/config/abi_suffix.hpp>