annotate DEPENDENCIES/generic/include/boost/thread/win32/thread_primitives.hpp @ 125:34e428693f5d vext

Vext -> Repoint
author Chris Cannam
date Thu, 14 Jun 2018 11:15:39 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 #ifndef BOOST_WIN32_THREAD_PRIMITIVES_HPP
Chris@16 2 #define BOOST_WIN32_THREAD_PRIMITIVES_HPP
Chris@16 3
Chris@16 4 // win32_thread_primitives.hpp
Chris@16 5 //
Chris@16 6 // (C) Copyright 2005-7 Anthony Williams
Chris@16 7 // (C) Copyright 2007 David Deakins
Chris@16 8 //
Chris@16 9 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 10 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 11 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 12
Chris@16 13 #include <boost/thread/detail/config.hpp>
Chris@101 14 #include <boost/predef/platform.h>
Chris@16 15 #include <boost/throw_exception.hpp>
Chris@16 16 #include <boost/assert.hpp>
Chris@16 17 #include <boost/thread/exceptions.hpp>
Chris@16 18 #include <boost/detail/interlocked.hpp>
Chris@16 19 //#include <boost/detail/winapi/synchronization.hpp>
Chris@16 20 #include <algorithm>
Chris@16 21
Chris@101 22 #if BOOST_PLAT_WINDOWS_RUNTIME
Chris@101 23 #include <thread>
Chris@16 24 #endif
Chris@16 25
Chris@16 26 #if defined( BOOST_USE_WINDOWS_H )
Chris@16 27 # include <windows.h>
Chris@16 28
Chris@16 29 namespace boost
Chris@16 30 {
Chris@16 31 namespace detail
Chris@16 32 {
Chris@16 33 namespace win32
Chris@16 34 {
Chris@16 35 typedef HANDLE handle;
Chris@101 36 typedef SYSTEM_INFO system_info;
Chris@101 37 typedef unsigned __int64 ticks_type;
Chris@16 38 unsigned const infinite=INFINITE;
Chris@16 39 unsigned const timeout=WAIT_TIMEOUT;
Chris@16 40 handle const invalid_handle_value=INVALID_HANDLE_VALUE;
Chris@16 41 unsigned const event_modify_state=EVENT_MODIFY_STATE;
Chris@16 42 unsigned const synchronize=SYNCHRONIZE;
Chris@16 43 unsigned const wait_abandoned=WAIT_ABANDONED;
Chris@101 44 unsigned const create_event_initial_set = 0x00000002;
Chris@101 45 unsigned const create_event_manual_reset = 0x00000001;
Chris@101 46 unsigned const event_all_access = EVENT_ALL_ACCESS;
Chris@101 47 unsigned const semaphore_all_access = SEMAPHORE_ALL_ACCESS;
Chris@101 48
Chris@16 49
Chris@16 50 # ifdef BOOST_NO_ANSI_APIS
Chris@101 51 # if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
Chris@16 52 using ::CreateMutexW;
Chris@16 53 using ::CreateEventW;
Chris@101 54 using ::CreateSemaphoreW;
Chris@101 55 # else
Chris@101 56 using ::CreateMutexExW;
Chris@101 57 using ::CreateEventExW;
Chris@101 58 using ::CreateSemaphoreExW;
Chris@101 59 # endif
Chris@16 60 using ::OpenEventW;
Chris@16 61 # else
Chris@16 62 using ::CreateMutexA;
Chris@16 63 using ::CreateEventA;
Chris@16 64 using ::OpenEventA;
Chris@16 65 using ::CreateSemaphoreA;
Chris@16 66 # endif
Chris@101 67 #if BOOST_PLAT_WINDOWS_RUNTIME
Chris@101 68 using ::GetNativeSystemInfo;
Chris@101 69 using ::GetTickCount64;
Chris@101 70 #else
Chris@101 71 using ::GetSystemInfo;
Chris@101 72 #endif
Chris@16 73 using ::CloseHandle;
Chris@16 74 using ::ReleaseMutex;
Chris@16 75 using ::ReleaseSemaphore;
Chris@16 76 using ::SetEvent;
Chris@16 77 using ::ResetEvent;
Chris@101 78 using ::WaitForMultipleObjectsEx;
Chris@101 79 using ::WaitForSingleObjectEx;
Chris@16 80 using ::GetCurrentProcessId;
Chris@16 81 using ::GetCurrentThreadId;
Chris@16 82 using ::GetCurrentThread;
Chris@16 83 using ::GetCurrentProcess;
Chris@16 84 using ::DuplicateHandle;
Chris@101 85 #if !BOOST_PLAT_WINDOWS_RUNTIME
Chris@16 86 using ::SleepEx;
Chris@16 87 using ::Sleep;
Chris@16 88 using ::QueueUserAPC;
Chris@101 89 #endif
Chris@16 90 }
Chris@16 91 }
Chris@16 92 }
Chris@16 93 #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ )
Chris@16 94
Chris@16 95 # ifdef UNDER_CE
Chris@16 96 # ifndef WINAPI
Chris@16 97 # ifndef _WIN32_WCE_EMULATION
Chris@16 98 # define WINAPI __cdecl // Note this doesn't match the desktop definition
Chris@16 99 # else
Chris@16 100 # define WINAPI __stdcall
Chris@16 101 # endif
Chris@16 102 # endif
Chris@16 103
Chris@16 104 # ifdef __cplusplus
Chris@16 105 extern "C" {
Chris@16 106 # endif
Chris@16 107 typedef int BOOL;
Chris@16 108 typedef unsigned long DWORD;
Chris@16 109 typedef void* HANDLE;
Chris@16 110 # include <kfuncs.h>
Chris@16 111 # ifdef __cplusplus
Chris@16 112 }
Chris@16 113 # endif
Chris@16 114 # endif
Chris@16 115
Chris@101 116 # ifdef __cplusplus
Chris@101 117 extern "C" {
Chris@101 118 # endif
Chris@101 119 struct _SYSTEM_INFO;
Chris@101 120 # ifdef __cplusplus
Chris@101 121 }
Chris@101 122 #endif
Chris@16 123
Chris@16 124 namespace boost
Chris@16 125 {
Chris@16 126 namespace detail
Chris@16 127 {
Chris@16 128 namespace win32
Chris@16 129 {
Chris@16 130 # ifdef _WIN64
Chris@16 131 typedef unsigned __int64 ulong_ptr;
Chris@16 132 # else
Chris@16 133 typedef unsigned long ulong_ptr;
Chris@16 134 # endif
Chris@16 135 typedef void* handle;
Chris@101 136 typedef _SYSTEM_INFO system_info;
Chris@101 137 typedef unsigned __int64 ticks_type;
Chris@16 138 unsigned const infinite=~0U;
Chris@16 139 unsigned const timeout=258U;
Chris@16 140 handle const invalid_handle_value=(handle)(-1);
Chris@16 141 unsigned const event_modify_state=2;
Chris@16 142 unsigned const synchronize=0x100000u;
Chris@16 143 unsigned const wait_abandoned=0x00000080u;
Chris@101 144 unsigned const create_event_initial_set = 0x00000002;
Chris@101 145 unsigned const create_event_manual_reset = 0x00000001;
Chris@101 146 unsigned const event_all_access = 0x1F0003;
Chris@101 147 unsigned const semaphore_all_access = 0x1F0003;
Chris@16 148
Chris@16 149 extern "C"
Chris@16 150 {
Chris@16 151 struct _SECURITY_ATTRIBUTES;
Chris@16 152 # ifdef BOOST_NO_ANSI_APIS
Chris@101 153 # if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
Chris@16 154 __declspec(dllimport) void* __stdcall CreateMutexW(_SECURITY_ATTRIBUTES*,int,wchar_t const*);
Chris@16 155 __declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*);
Chris@16 156 __declspec(dllimport) void* __stdcall CreateEventW(_SECURITY_ATTRIBUTES*,int,int,wchar_t const*);
Chris@101 157 # else
Chris@101 158 __declspec(dllimport) void* __stdcall CreateMutexExW(_SECURITY_ATTRIBUTES*,wchar_t const*,unsigned long,unsigned long);
Chris@101 159 __declspec(dllimport) void* __stdcall CreateEventExW(_SECURITY_ATTRIBUTES*,wchar_t const*,unsigned long,unsigned long);
Chris@101 160 __declspec(dllimport) void* __stdcall CreateSemaphoreExW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*,unsigned long,unsigned long);
Chris@101 161 # endif
Chris@16 162 __declspec(dllimport) void* __stdcall OpenEventW(unsigned long,int,wchar_t const*);
Chris@16 163 # else
Chris@16 164 __declspec(dllimport) void* __stdcall CreateMutexA(_SECURITY_ATTRIBUTES*,int,char const*);
Chris@16 165 __declspec(dllimport) void* __stdcall CreateSemaphoreA(_SECURITY_ATTRIBUTES*,long,long,char const*);
Chris@16 166 __declspec(dllimport) void* __stdcall CreateEventA(_SECURITY_ATTRIBUTES*,int,int,char const*);
Chris@16 167 __declspec(dllimport) void* __stdcall OpenEventA(unsigned long,int,char const*);
Chris@16 168 # endif
Chris@101 169 #if BOOST_PLAT_WINDOWS_RUNTIME
Chris@101 170 __declspec(dllimport) void __stdcall GetNativeSystemInfo(_SYSTEM_INFO*);
Chris@101 171 __declspec(dllimport) ticks_type __stdcall GetTickCount64();
Chris@101 172 #else
Chris@101 173 __declspec(dllimport) void __stdcall GetSystemInfo(_SYSTEM_INFO*);
Chris@101 174 #endif
Chris@16 175 __declspec(dllimport) int __stdcall CloseHandle(void*);
Chris@16 176 __declspec(dllimport) int __stdcall ReleaseMutex(void*);
Chris@101 177 __declspec(dllimport) unsigned long __stdcall WaitForSingleObjectEx(void*,unsigned long,int);
Chris@101 178 __declspec(dllimport) unsigned long __stdcall WaitForMultipleObjectsEx(unsigned long nCount,void* const * lpHandles,int bWaitAll,unsigned long dwMilliseconds,int bAlertable);
Chris@16 179 __declspec(dllimport) int __stdcall ReleaseSemaphore(void*,long,long*);
Chris@16 180 __declspec(dllimport) int __stdcall DuplicateHandle(void*,void*,void*,void**,unsigned long,int,unsigned long);
Chris@101 181 #if !BOOST_PLAT_WINDOWS_RUNTIME
Chris@16 182 __declspec(dllimport) unsigned long __stdcall SleepEx(unsigned long,int);
Chris@16 183 __declspec(dllimport) void __stdcall Sleep(unsigned long);
Chris@16 184 typedef void (__stdcall *queue_user_apc_callback_function)(ulong_ptr);
Chris@16 185 __declspec(dllimport) unsigned long __stdcall QueueUserAPC(queue_user_apc_callback_function,void*,ulong_ptr);
Chris@101 186 #endif
Chris@16 187
Chris@16 188 # ifndef UNDER_CE
Chris@16 189 __declspec(dllimport) unsigned long __stdcall GetCurrentProcessId();
Chris@16 190 __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId();
Chris@16 191 __declspec(dllimport) void* __stdcall GetCurrentThread();
Chris@16 192 __declspec(dllimport) void* __stdcall GetCurrentProcess();
Chris@16 193 __declspec(dllimport) int __stdcall SetEvent(void*);
Chris@16 194 __declspec(dllimport) int __stdcall ResetEvent(void*);
Chris@16 195 # else
Chris@16 196 using ::GetCurrentProcessId;
Chris@16 197 using ::GetCurrentThreadId;
Chris@16 198 using ::GetCurrentThread;
Chris@16 199 using ::GetCurrentProcess;
Chris@16 200 using ::SetEvent;
Chris@16 201 using ::ResetEvent;
Chris@16 202 # endif
Chris@16 203 }
Chris@16 204 }
Chris@16 205 }
Chris@16 206 }
Chris@16 207 #else
Chris@16 208 # error "Win32 functions not available"
Chris@16 209 #endif
Chris@16 210
Chris@16 211 #include <boost/config/abi_prefix.hpp>
Chris@16 212
Chris@16 213 namespace boost
Chris@16 214 {
Chris@16 215 namespace detail
Chris@16 216 {
Chris@16 217 namespace win32
Chris@16 218 {
Chris@101 219 namespace detail { typedef int (__stdcall *farproc_t)(); typedef ticks_type (__stdcall *gettickcount64_t)(); }
Chris@101 220 #if !BOOST_PLAT_WINDOWS_RUNTIME
Chris@101 221 extern "C"
Chris@101 222 {
Chris@101 223 __declspec(dllimport) detail::farproc_t __stdcall GetProcAddress(void *, const char *);
Chris@101 224 #if !defined(BOOST_NO_ANSI_APIS)
Chris@101 225 __declspec(dllimport) void * __stdcall GetModuleHandleA(const char *);
Chris@101 226 #else
Chris@101 227 __declspec(dllimport) void * __stdcall GetModuleHandleW(const wchar_t *);
Chris@101 228 #endif
Chris@101 229 __declspec(dllimport) unsigned long __stdcall GetTickCount();
Chris@101 230 #ifdef _MSC_VER
Chris@101 231 long _InterlockedCompareExchange(long volatile *, long, long);
Chris@101 232 #pragma intrinsic(_InterlockedCompareExchange)
Chris@101 233 #elif defined(__MINGW64_VERSION_MAJOR)
Chris@101 234 long _InterlockedCompareExchange(long volatile *, long, long);
Chris@101 235 #else
Chris@101 236 // Mingw doesn't provide intrinsics
Chris@101 237 #define _InterlockedCompareExchange InterlockedCompareExchange
Chris@101 238 #endif
Chris@101 239 }
Chris@101 240 // Borrowed from https://stackoverflow.com/questions/8211820/userland-interrupt-timer-access-such-as-via-kequeryinterrupttime-or-similar
Chris@101 241 inline ticks_type __stdcall GetTickCount64emulation()
Chris@101 242 {
Chris@101 243 static volatile long count = 0xFFFFFFFF;
Chris@101 244 unsigned long previous_count, current_tick32, previous_count_zone, current_tick32_zone;
Chris@101 245 ticks_type current_tick64;
Chris@101 246
Chris@101 247 previous_count = (unsigned long) _InterlockedCompareExchange(&count, 0, 0);
Chris@101 248 current_tick32 = GetTickCount();
Chris@101 249
Chris@101 250 if(previous_count == 0xFFFFFFFF)
Chris@101 251 {
Chris@101 252 // count has never been written
Chris@101 253 unsigned long initial_count;
Chris@101 254 initial_count = current_tick32 >> 28;
Chris@101 255 previous_count = (unsigned long) _InterlockedCompareExchange(&count, initial_count, 0xFFFFFFFF);
Chris@101 256
Chris@101 257 current_tick64 = initial_count;
Chris@101 258 current_tick64 <<= 28;
Chris@101 259 current_tick64 += current_tick32 & 0x0FFFFFFF;
Chris@101 260 return current_tick64;
Chris@101 261 }
Chris@101 262
Chris@101 263 previous_count_zone = previous_count & 15;
Chris@101 264 current_tick32_zone = current_tick32 >> 28;
Chris@101 265
Chris@101 266 if(current_tick32_zone == previous_count_zone)
Chris@101 267 {
Chris@101 268 // The top four bits of the 32-bit tick count haven't changed since count was last written.
Chris@101 269 current_tick64 = previous_count;
Chris@101 270 current_tick64 <<= 28;
Chris@101 271 current_tick64 += current_tick32 & 0x0FFFFFFF;
Chris@101 272 return current_tick64;
Chris@101 273 }
Chris@101 274
Chris@101 275 if(current_tick32_zone == previous_count_zone + 1 || (current_tick32_zone == 0 && previous_count_zone == 15))
Chris@101 276 {
Chris@101 277 // The top four bits of the 32-bit tick count have been incremented since count was last written.
Chris@101 278 _InterlockedCompareExchange(&count, previous_count + 1, previous_count);
Chris@101 279 current_tick64 = previous_count + 1;
Chris@101 280 current_tick64 <<= 28;
Chris@101 281 current_tick64 += current_tick32 & 0x0FFFFFFF;
Chris@101 282 return current_tick64;
Chris@101 283 }
Chris@101 284
Chris@101 285 // Oops, we weren't called often enough, we're stuck
Chris@101 286 return 0xFFFFFFFF;
Chris@101 287 }
Chris@101 288 #endif
Chris@101 289 inline detail::gettickcount64_t GetTickCount64_()
Chris@101 290 {
Chris@101 291 static detail::gettickcount64_t gettickcount64impl;
Chris@101 292 if(gettickcount64impl)
Chris@101 293 return gettickcount64impl;
Chris@101 294
Chris@101 295 // GetTickCount and GetModuleHandle are not allowed in the Windows Runtime,
Chris@101 296 // and kernel32 isn't used in Windows Phone.
Chris@101 297 #if BOOST_PLAT_WINDOWS_RUNTIME
Chris@101 298 gettickcount64impl = &GetTickCount64;
Chris@101 299 #else
Chris@101 300 detail::farproc_t addr=GetProcAddress(
Chris@101 301 #if !defined(BOOST_NO_ANSI_APIS)
Chris@101 302 GetModuleHandleA("KERNEL32.DLL"),
Chris@101 303 #else
Chris@101 304 GetModuleHandleW(L"KERNEL32.DLL"),
Chris@101 305 #endif
Chris@101 306 "GetTickCount64");
Chris@101 307 if(addr)
Chris@101 308 gettickcount64impl=(detail::gettickcount64_t) addr;
Chris@101 309 else
Chris@101 310 gettickcount64impl=&GetTickCount64emulation;
Chris@101 311 #endif
Chris@101 312 return gettickcount64impl;
Chris@101 313 }
Chris@101 314
Chris@16 315 enum event_type
Chris@16 316 {
Chris@16 317 auto_reset_event=false,
Chris@16 318 manual_reset_event=true
Chris@16 319 };
Chris@16 320
Chris@16 321 enum initial_event_state
Chris@16 322 {
Chris@16 323 event_initially_reset=false,
Chris@16 324 event_initially_set=true
Chris@16 325 };
Chris@16 326
Chris@101 327 inline handle create_event(
Chris@101 328 #if !defined(BOOST_NO_ANSI_APIS)
Chris@101 329 const char *mutex_name,
Chris@101 330 #else
Chris@101 331 const wchar_t *mutex_name,
Chris@101 332 #endif
Chris@101 333 event_type type,
Chris@101 334 initial_event_state state)
Chris@101 335 {
Chris@101 336 #if !defined(BOOST_NO_ANSI_APIS)
Chris@101 337 handle const res = win32::CreateEventA(0, type, state, mutex_name);
Chris@101 338 #elif BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
Chris@101 339 handle const res = win32::CreateEventW(0, type, state, mutex_name);
Chris@101 340 #else
Chris@101 341 handle const res = win32::CreateEventExW(
Chris@101 342 0,
Chris@101 343 mutex_name,
Chris@101 344 type ? create_event_manual_reset : 0 | state ? create_event_initial_set : 0,
Chris@101 345 event_all_access);
Chris@101 346 #endif
Chris@101 347 return res;
Chris@101 348 }
Chris@101 349
Chris@16 350 inline handle create_anonymous_event(event_type type,initial_event_state state)
Chris@16 351 {
Chris@101 352 handle const res = create_event(0, type, state);
Chris@16 353 if(!res)
Chris@16 354 {
Chris@16 355 boost::throw_exception(thread_resource_error());
Chris@16 356 }
Chris@16 357 return res;
Chris@16 358 }
Chris@16 359
Chris@101 360 inline handle create_anonymous_semaphore_nothrow(long initial_count,long max_count)
Chris@101 361 {
Chris@101 362 #if !defined(BOOST_NO_ANSI_APIS)
Chris@101 363 handle const res=win32::CreateSemaphoreA(0,initial_count,max_count,0);
Chris@101 364 #else
Chris@101 365 #if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
Chris@101 366 handle const res=win32::CreateSemaphoreEx(0,initial_count,max_count,0,0);
Chris@101 367 #else
Chris@101 368 handle const res=win32::CreateSemaphoreExW(0,initial_count,max_count,0,0,semaphore_all_access);
Chris@101 369 #endif
Chris@101 370 #endif
Chris@101 371 return res;
Chris@101 372 }
Chris@101 373
Chris@16 374 inline handle create_anonymous_semaphore(long initial_count,long max_count)
Chris@16 375 {
Chris@101 376 handle const res=create_anonymous_semaphore_nothrow(initial_count,max_count);
Chris@16 377 if(!res)
Chris@16 378 {
Chris@16 379 boost::throw_exception(thread_resource_error());
Chris@16 380 }
Chris@16 381 return res;
Chris@16 382 }
Chris@16 383
Chris@16 384 inline handle duplicate_handle(handle source)
Chris@16 385 {
Chris@16 386 handle const current_process=GetCurrentProcess();
Chris@16 387 long const same_access_flag=2;
Chris@16 388 handle new_handle=0;
Chris@16 389 bool const success=DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0;
Chris@16 390 if(!success)
Chris@16 391 {
Chris@16 392 boost::throw_exception(thread_resource_error());
Chris@16 393 }
Chris@16 394 return new_handle;
Chris@16 395 }
Chris@16 396
Chris@16 397 inline void release_semaphore(handle semaphore,long count)
Chris@16 398 {
Chris@16 399 BOOST_VERIFY(ReleaseSemaphore(semaphore,count,0)!=0);
Chris@16 400 }
Chris@101 401
Chris@101 402 inline void get_system_info(system_info *info)
Chris@101 403 {
Chris@101 404 #if BOOST_PLAT_WINDOWS_RUNTIME
Chris@101 405 win32::GetNativeSystemInfo(info);
Chris@101 406 #else
Chris@101 407 win32::GetSystemInfo(info);
Chris@101 408 #endif
Chris@101 409 }
Chris@101 410
Chris@101 411 inline void sleep(unsigned long milliseconds)
Chris@101 412 {
Chris@101 413 if(milliseconds == 0)
Chris@101 414 {
Chris@101 415 #if BOOST_PLAT_WINDOWS_RUNTIME
Chris@101 416 std::this_thread::yield();
Chris@101 417 #else
Chris@101 418 ::boost::detail::win32::Sleep(0);
Chris@101 419 #endif
Chris@101 420 }
Chris@101 421 else
Chris@101 422 {
Chris@101 423 #if BOOST_PLAT_WINDOWS_RUNTIME
Chris@101 424 ::boost::detail::win32::WaitForSingleObjectEx(::boost::detail::win32::GetCurrentThread(), milliseconds, 0);
Chris@101 425 #else
Chris@101 426 ::boost::detail::win32::Sleep(milliseconds);
Chris@101 427 #endif
Chris@101 428 }
Chris@101 429 }
Chris@101 430
Chris@101 431 #if BOOST_PLAT_WINDOWS_RUNTIME
Chris@101 432 class BOOST_THREAD_DECL scoped_winrt_thread
Chris@101 433 {
Chris@101 434 public:
Chris@101 435 scoped_winrt_thread() : m_completionHandle(invalid_handle_value)
Chris@101 436 {}
Chris@16 437
Chris@101 438 ~scoped_winrt_thread()
Chris@101 439 {
Chris@101 440 if (m_completionHandle != ::boost::detail::win32::invalid_handle_value)
Chris@101 441 {
Chris@101 442 CloseHandle(m_completionHandle);
Chris@101 443 }
Chris@101 444 }
Chris@101 445
Chris@101 446 typedef unsigned(__stdcall * thread_func)(void *);
Chris@101 447 bool start(thread_func address, void *parameter, unsigned int *thrdId);
Chris@101 448
Chris@101 449 handle waitable_handle() const
Chris@101 450 {
Chris@101 451 BOOST_ASSERT(m_completionHandle != ::boost::detail::win32::invalid_handle_value);
Chris@101 452 return m_completionHandle;
Chris@101 453 }
Chris@101 454
Chris@101 455 private:
Chris@101 456 handle m_completionHandle;
Chris@101 457 };
Chris@101 458 #endif
Chris@16 459 class BOOST_THREAD_DECL handle_manager
Chris@16 460 {
Chris@16 461 private:
Chris@16 462 handle handle_to_manage;
Chris@16 463 handle_manager(handle_manager&);
Chris@16 464 handle_manager& operator=(handle_manager&);
Chris@16 465
Chris@16 466 void cleanup()
Chris@16 467 {
Chris@16 468 if(handle_to_manage && handle_to_manage!=invalid_handle_value)
Chris@16 469 {
Chris@16 470 BOOST_VERIFY(CloseHandle(handle_to_manage));
Chris@16 471 }
Chris@16 472 }
Chris@16 473
Chris@16 474 public:
Chris@16 475 explicit handle_manager(handle handle_to_manage_):
Chris@16 476 handle_to_manage(handle_to_manage_)
Chris@16 477 {}
Chris@16 478 handle_manager():
Chris@16 479 handle_to_manage(0)
Chris@16 480 {}
Chris@16 481
Chris@16 482 handle_manager& operator=(handle new_handle)
Chris@16 483 {
Chris@16 484 cleanup();
Chris@16 485 handle_to_manage=new_handle;
Chris@16 486 return *this;
Chris@16 487 }
Chris@16 488
Chris@16 489 operator handle() const
Chris@16 490 {
Chris@16 491 return handle_to_manage;
Chris@16 492 }
Chris@16 493
Chris@16 494 handle duplicate() const
Chris@16 495 {
Chris@16 496 return duplicate_handle(handle_to_manage);
Chris@16 497 }
Chris@16 498
Chris@16 499 void swap(handle_manager& other)
Chris@16 500 {
Chris@16 501 std::swap(handle_to_manage,other.handle_to_manage);
Chris@16 502 }
Chris@16 503
Chris@16 504 handle release()
Chris@16 505 {
Chris@16 506 handle const res=handle_to_manage;
Chris@16 507 handle_to_manage=0;
Chris@16 508 return res;
Chris@16 509 }
Chris@16 510
Chris@16 511 bool operator!() const
Chris@16 512 {
Chris@16 513 return !handle_to_manage;
Chris@16 514 }
Chris@16 515
Chris@16 516 ~handle_manager()
Chris@16 517 {
Chris@16 518 cleanup();
Chris@16 519 }
Chris@16 520 };
Chris@16 521 }
Chris@16 522 }
Chris@16 523 }
Chris@16 524
Chris@16 525 #if defined(BOOST_MSVC) && (_MSC_VER>=1400) && !defined(UNDER_CE)
Chris@16 526
Chris@16 527 namespace boost
Chris@16 528 {
Chris@16 529 namespace detail
Chris@16 530 {
Chris@16 531 namespace win32
Chris@16 532 {
Chris@16 533 #if _MSC_VER==1400
Chris@16 534 extern "C" unsigned char _interlockedbittestandset(long *a,long b);
Chris@16 535 extern "C" unsigned char _interlockedbittestandreset(long *a,long b);
Chris@16 536 #else
Chris@16 537 extern "C" unsigned char _interlockedbittestandset(volatile long *a,long b);
Chris@16 538 extern "C" unsigned char _interlockedbittestandreset(volatile long *a,long b);
Chris@16 539 #endif
Chris@16 540
Chris@16 541 #pragma intrinsic(_interlockedbittestandset)
Chris@16 542 #pragma intrinsic(_interlockedbittestandreset)
Chris@16 543
Chris@16 544 inline bool interlocked_bit_test_and_set(long* x,long bit)
Chris@16 545 {
Chris@16 546 return _interlockedbittestandset(x,bit)!=0;
Chris@16 547 }
Chris@16 548
Chris@16 549 inline bool interlocked_bit_test_and_reset(long* x,long bit)
Chris@16 550 {
Chris@16 551 return _interlockedbittestandreset(x,bit)!=0;
Chris@16 552 }
Chris@16 553
Chris@16 554 }
Chris@16 555 }
Chris@16 556 }
Chris@16 557 #define BOOST_THREAD_BTS_DEFINED
Chris@16 558 #elif (defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)) && defined(_M_IX86)
Chris@16 559 namespace boost
Chris@16 560 {
Chris@16 561 namespace detail
Chris@16 562 {
Chris@16 563 namespace win32
Chris@16 564 {
Chris@16 565 inline bool interlocked_bit_test_and_set(long* x,long bit)
Chris@16 566 {
Chris@16 567 #ifndef BOOST_INTEL_CXX_VERSION
Chris@16 568 __asm {
Chris@16 569 mov eax,bit;
Chris@16 570 mov edx,x;
Chris@16 571 lock bts [edx],eax;
Chris@16 572 setc al;
Chris@16 573 };
Chris@16 574 #else
Chris@16 575 bool ret;
Chris@16 576 __asm {
Chris@16 577 mov eax,bit
Chris@16 578 mov edx,x
Chris@16 579 lock bts [edx],eax
Chris@16 580 setc al
Chris@16 581 mov ret, al
Chris@16 582 };
Chris@16 583 return ret;
Chris@16 584
Chris@16 585 #endif
Chris@16 586 }
Chris@16 587
Chris@16 588 inline bool interlocked_bit_test_and_reset(long* x,long bit)
Chris@16 589 {
Chris@16 590 #ifndef BOOST_INTEL_CXX_VERSION
Chris@16 591 __asm {
Chris@16 592 mov eax,bit;
Chris@16 593 mov edx,x;
Chris@16 594 lock btr [edx],eax;
Chris@16 595 setc al;
Chris@16 596 };
Chris@16 597 #else
Chris@16 598 bool ret;
Chris@16 599 __asm {
Chris@16 600 mov eax,bit
Chris@16 601 mov edx,x
Chris@16 602 lock btr [edx],eax
Chris@16 603 setc al
Chris@16 604 mov ret, al
Chris@16 605 };
Chris@16 606 return ret;
Chris@16 607
Chris@16 608 #endif
Chris@16 609 }
Chris@16 610
Chris@16 611 }
Chris@16 612 }
Chris@16 613 }
Chris@16 614 #define BOOST_THREAD_BTS_DEFINED
Chris@16 615 #endif
Chris@16 616
Chris@16 617 #ifndef BOOST_THREAD_BTS_DEFINED
Chris@16 618
Chris@16 619 namespace boost
Chris@16 620 {
Chris@16 621 namespace detail
Chris@16 622 {
Chris@16 623 namespace win32
Chris@16 624 {
Chris@16 625 inline bool interlocked_bit_test_and_set(long* x,long bit)
Chris@16 626 {
Chris@16 627 long const value=1<<bit;
Chris@16 628 long old=*x;
Chris@16 629 do
Chris@16 630 {
Chris@16 631 long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old|value,old);
Chris@16 632 if(current==old)
Chris@16 633 {
Chris@16 634 break;
Chris@16 635 }
Chris@16 636 old=current;
Chris@16 637 }
Chris@16 638 while(true);
Chris@16 639 return (old&value)!=0;
Chris@16 640 }
Chris@16 641
Chris@16 642 inline bool interlocked_bit_test_and_reset(long* x,long bit)
Chris@16 643 {
Chris@16 644 long const value=1<<bit;
Chris@16 645 long old=*x;
Chris@16 646 do
Chris@16 647 {
Chris@16 648 long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old&~value,old);
Chris@16 649 if(current==old)
Chris@16 650 {
Chris@16 651 break;
Chris@16 652 }
Chris@16 653 old=current;
Chris@16 654 }
Chris@16 655 while(true);
Chris@16 656 return (old&value)!=0;
Chris@16 657 }
Chris@16 658 }
Chris@16 659 }
Chris@16 660 }
Chris@16 661 #endif
Chris@16 662
Chris@16 663 #include <boost/config/abi_suffix.hpp>
Chris@16 664
Chris@16 665 #endif