|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r86179 - in trunk/boost: detail/winapi sync/detail sync/detail/condition_variables sync/detail/event
From: andrey.semashev_at_[hidden]
Date: 2013-10-06 13:40:19
Author: andysem
Date: 2013-10-06 13:40:19 EDT (Sun, 06 Oct 2013)
New Revision: 86179
URL: http://svn.boost.org/trac/boost/changeset/86179
Log:
Boost.Sync: Added preliminary implementation of a waitable timer for fixed time point waits. Updated WinAPI functions to contain the required APIs.
Added:
trunk/boost/detail/winapi/thread_pool.hpp (contents, props changed)
trunk/boost/detail/winapi/tls.hpp (contents, props changed)
trunk/boost/detail/winapi/waitable_timer.hpp (contents, props changed)
trunk/boost/sync/detail/waitable_timer.hpp (contents, props changed)
trunk/boost/sync/detail/weak_linkage.hpp (contents, props changed)
Deleted:
trunk/boost/sync/detail/windows_primitives.hpp
Text files modified:
trunk/boost/detail/winapi/basic_types.hpp | 25 ++
trunk/boost/detail/winapi/dll.hpp | 30 ++
trunk/boost/detail/winapi/process.hpp | 7
trunk/boost/detail/winapi/synchronization.hpp | 121 +++++++++----
trunk/boost/detail/winapi/thread.hpp | 18 +-
trunk/boost/detail/winapi/thread_pool.hpp | 102 +++++++++++
trunk/boost/detail/winapi/tls.hpp | 49 +++++
trunk/boost/detail/winapi/waitable_timer.hpp | 110 ++++++++++++
trunk/boost/sync/detail/condition_variables/basic_condition_variable_windows.hpp | 7
trunk/boost/sync/detail/event/event_windows.hpp | 14
trunk/boost/sync/detail/waitable_timer.hpp | 345 ++++++++++++++++++++++++++++++++++++++++
trunk/boost/sync/detail/weak_linkage.hpp | 49 +++++
/dev/null | 65 -------
13 files changed, 802 insertions(+), 140 deletions(-)
Modified: trunk/boost/detail/winapi/basic_types.hpp
==============================================================================
--- trunk/boost/detail/winapi/basic_types.hpp Sun Oct 6 13:12:46 2013 (r86178)
+++ trunk/boost/detail/winapi/basic_types.hpp 2013-10-06 13:40:19 EDT (Sun, 06 Oct 2013) (r86179)
@@ -31,6 +31,9 @@
# define WINAPI __stdcall
# endif
# endif
+# ifndef NTAPI
+# define NTAPI __stdcall
+# endif
#else
# error "Win32 functions not available"
#endif
@@ -44,11 +47,19 @@
namespace winapi {
#if defined( BOOST_USE_WINDOWS_H )
typedef ::BOOL BOOL_;
+ typedef ::BOOLEAN BOOLEAN_;
+ typedef ::PBOOLEAN PBOOLEAN_;
+ typedef ::BYTE BYTE_;
typedef ::WORD WORD_;
typedef ::DWORD DWORD_;
typedef ::HANDLE HANDLE_;
+ typedef ::HMODULE HMODULE_;
typedef ::LONG LONG_;
+ typedef ::ULONG ULONG_;
typedef ::LONGLONG LONGLONG_;
+ typedef ::INT_PTR INT_PTR_;
+ typedef ::UINT_PTR UINT_PTR_;
+ typedef ::LONG_PTR LONG_PTR_;
typedef ::ULONG_PTR ULONG_PTR_;
typedef ::LARGE_INTEGER LARGE_INTEGER_;
typedef ::PLARGE_INTEGER PLARGE_INTEGER_;
@@ -63,11 +74,16 @@
#else
extern "C" {
typedef int BOOL_;
+ typedef unsigned char BYTE_;
+ typedef BYTE_ BOOLEAN_;
+ typedef BOOLEAN_* PBOOLEAN_;
typedef unsigned short WORD_;
typedef unsigned long DWORD_;
typedef void* HANDLE_;
+ typedef void* HMODULE_;
typedef long LONG_;
+ typedef unsigned long ULONG_;
// @FIXME Which condition must be tested
//~ #if !defined(_M_IX86)
@@ -84,11 +100,20 @@
// @FIXME Which condition must be tested
# ifdef _WIN64
#if defined(__CYGWIN__)
+ typedef long INT_PTR_;
+ typedef unsigned long INT_PTR_;
+ typedef long LONG_PTR_;
typedef unsigned long ULONG_PTR_;
#else
+ typedef __int64 INT_PTR_;
+ typedef unsigned __int64 UINT_PTR_;
+ typedef __int64 LONG_PTR_;
typedef unsigned __int64 ULONG_PTR_;
#endif
# else
+ typedef int INT_PTR_;
+ typedef unsigned int INT_PTR_;
+ typedef long LONG_PTR_;
typedef unsigned long ULONG_PTR_;
# endif
Modified: trunk/boost/detail/winapi/dll.hpp
==============================================================================
--- trunk/boost/detail/winapi/dll.hpp Sun Oct 6 13:12:46 2013 (r86178)
+++ trunk/boost/detail/winapi/dll.hpp 2013-10-06 13:40:19 EDT (Sun, 06 Oct 2013) (r86179)
@@ -23,33 +23,47 @@
namespace winapi
{
#if defined( BOOST_USE_WINDOWS_H )
+ typedef ::FARPROC FARPROC_;
+ typedef ::NEARPROC NEARPROC_;
+ typedef ::PROC PROC_;
+
using ::LoadLibrary;
using ::FreeLibrary;
using ::GetProcAddress;
using ::GetModuleHandleA;
#else
-extern "C" {
- __declspec(dllimport) HMODULE_ __stdcall
+extern "C" {
+#ifdef _WIN64
+ typedef INT_PTR (WINAPI *FARPROC_)();
+ typedef INT_PTR (WINAPI *NEARPROC_)();
+ typedef INT_PTR (WINAPI *PROC_)();
+#else
+ typedef int (WINAPI *FARPROC_)();
+ typedef int (WINAPI *NEARPROC_)();
+ typedef int (WINAPI *PROC_)();
+#endif // _WIN64
+
+ __declspec(dllimport) HMODULE_ WINAPI
LoadLibrary(
LPCTSTR_ lpFileName
);
- __declspec(dllimport) BOOL_ __stdcall
+ __declspec(dllimport) BOOL_ WINAPI
FreeLibrary(
HMODULE_ hModule
);
- __declspec(dllimport) FARPROC_ __stdcall
+ __declspec(dllimport) FARPROC_ WINAPI
GetProcAddress(
HMODULE_ hModule,
LPCSTR_ lpProcName
);
- __declspec(dllimport) FARPROC_ __stdcall
+ __declspec(dllimport) HMODULE_ WINAPI
GetModuleHandleA(
- LPCSTR_ lpProcName
+ LPCSTR_ lpFileName
);
-}
+}
#endif
}
}
}
-#endif // BOOST_DETAIL_WINAPI_THREAD_HPP
+#endif // BOOST_DETAIL_WINAPI_DLL_HPP
Modified: trunk/boost/detail/winapi/process.hpp
==============================================================================
--- trunk/boost/detail/winapi/process.hpp Sun Oct 6 13:12:46 2013 (r86178)
+++ trunk/boost/detail/winapi/process.hpp 2013-10-06 13:40:19 EDT (Sun, 06 Oct 2013) (r86179)
@@ -23,10 +23,9 @@
using ::GetCurrentProcessId;
#else
# ifndef UNDER_CE
-extern "C" {
- __declspec(dllimport) unsigned long __stdcall
- GetCurrentProcessId(void);
-}
+extern "C" {
+ __declspec(dllimport) DWORD_ WINAPI GetCurrentProcessId(void);
+}
# else
using ::GetCurrentProcessId;
# endif
Modified: trunk/boost/detail/winapi/synchronization.hpp
==============================================================================
--- trunk/boost/detail/winapi/synchronization.hpp Sun Oct 6 13:12:46 2013 (r86178)
+++ trunk/boost/detail/winapi/synchronization.hpp 2013-10-06 13:40:19 EDT (Sun, 06 Oct 2013) (r86179)
@@ -74,56 +74,64 @@
#endif
};
- __declspec(dllimport) void __stdcall
+ __declspec(dllimport) void WINAPI
InitializeCriticalSection(CRITICAL_SECTION_ *);
- __declspec(dllimport) void __stdcall
+ __declspec(dllimport) void WINAPI
EnterCriticalSection(CRITICAL_SECTION_ *);
- __declspec(dllimport) bool __stdcall
+ __declspec(dllimport) bool WINAPI
TryEnterCriticalSection(CRITICAL_SECTION_ *);
- __declspec(dllimport) void __stdcall
+ __declspec(dllimport) void WINAPI
LeaveCriticalSection(CRITICAL_SECTION_ *);
- __declspec(dllimport) void __stdcall
+ __declspec(dllimport) void WINAPI
DeleteCriticalSection(CRITICAL_SECTION_ *);
struct _SECURITY_ATTRIBUTES;
# ifdef BOOST_NO_ANSI_APIS
- __declspec(dllimport) void* __stdcall
- CreateMutexW(_SECURITY_ATTRIBUTES*,int,wchar_t const*);
- __declspec(dllimport) void* __stdcall
- CreateSemaphoreW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*);
- __declspec(dllimport) void* __stdcall
- CreateEventW(_SECURITY_ATTRIBUTES*,int,int,wchar_t const*);
- __declspec(dllimport) void* __stdcall
- OpenEventW(unsigned long,int,wchar_t const*);
+ __declspec(dllimport) HANDLE_ WINAPI
+ CreateMutexW(_SECURITY_ATTRIBUTES*, BOOL_, LPCWSTR_);
+ __declspec(dllimport) HANDLE_ WINAPI
+ OpenMutexW(DWORD_ dwDesiredAccess, BOOL_ bInheritHandle, LPCWSTR_ lpName);
+ __declspec(dllimport) HANDLE_ WINAPI
+ CreateSemaphoreW(_SECURITY_ATTRIBUTES*, LONG_, LONG_, LPCWSTR_);
+ __declspec(dllimport) HANDLE_ WINAPI
+ OpenSemaphoreW(DWORD_ dwDesiredAccess, BOOL_ bInheritHandle, LPCWSTR_ lpName);
+ __declspec(dllimport) HANDLE_ WINAPI
+ CreateEventW(_SECURITY_ATTRIBUTES*, BOOL_, BOOL_, LPCWSTR_);
+ __declspec(dllimport) HANDLE_ WINAPI
+ OpenEventW(DWORD_, BOOL_, LPCWSTR_);
# else
- __declspec(dllimport) void* __stdcall
- CreateMutexA(_SECURITY_ATTRIBUTES*,int,char const*);
- __declspec(dllimport) void* __stdcall
- CreateSemaphoreA(_SECURITY_ATTRIBUTES*,long,long,char const*);
- __declspec(dllimport) void* __stdcall
- CreateEventA(_SECURITY_ATTRIBUTES*,int,int,char const*);
- __declspec(dllimport) void* __stdcall
- OpenEventA(unsigned long,int,char const*);
+ __declspec(dllimport) HANDLE_ WINAPI
+ CreateMutexA(_SECURITY_ATTRIBUTES*, BOOL_, LPCSTR_);
+ __declspec(dllimport) HANDLE_ WINAPI
+ OpenMutexA(DWORD_ dwDesiredAccess, BOOL_ bInheritHandle, LPCSTR_ lpName);
+ __declspec(dllimport) HANDLE_ WINAPI
+ CreateSemaphoreA(_SECURITY_ATTRIBUTES*, LONG_, LONG_, LPCSTR_);
+ __declspec(dllimport) HANDLE_ WINAPI
+ OpenSemaphoreA(DWORD_ dwDesiredAccess, BOOL_ bInheritHandle, LPCSTR_ lpName);
+ __declspec(dllimport) HANDLE_ WINAPI
+ CreateEventA(_SECURITY_ATTRIBUTES*, BOOL_, BOOL_, LPCSTR_);
+ __declspec(dllimport) HANDLE_ WINAPI
+ OpenEventA(DWORD_, BOOL_, LPCSTR_);
# endif
- __declspec(dllimport) int __stdcall
- ReleaseMutex(void*);
- __declspec(dllimport) unsigned long __stdcall
- WaitForSingleObject(void*,unsigned long);
- __declspec(dllimport) unsigned long __stdcall
- WaitForMultipleObjects(unsigned long nCount,
- void* const * lpHandles,
- int bWaitAll,
- unsigned long dwMilliseconds);
- __declspec(dllimport) int __stdcall
- ReleaseSemaphore(void*,long,long*);
+ __declspec(dllimport) BOOL_ WINAPI
+ ReleaseMutex(HANDLE_);
+ __declspec(dllimport) DWORD_ WINAPI
+ WaitForSingleObject(HANDLE_, DWORD_);
+ __declspec(dllimport) DWORD_ WINAPI
+ WaitForMultipleObjects(DWORD_ nCount,
+ HANDLE_ const * lpHandles,
+ BOOL_ bWaitAll,
+ DWORD_ dwMilliseconds);
+ __declspec(dllimport) BOOL_ WINAPI
+ ReleaseSemaphore(HANDLE_, LONG_, LONG_*);
typedef void (__stdcall *PAPCFUNC8)(ULONG_PTR_);
- __declspec(dllimport) unsigned long __stdcall
- QueueUserAPC(PAPCFUNC8,void*,ULONG_PTR_);
+ __declspec(dllimport) DWORD_ WINAPI
+ QueueUserAPC(PAPCFUNC8, HANDLE_, ULONG_PTR_);
# ifndef UNDER_CE
- __declspec(dllimport) int __stdcall
- SetEvent(void*);
- __declspec(dllimport) int __stdcall
- ResetEvent(void*);
+ __declspec(dllimport) BOOL_ WINAPI
+ SetEvent(HANDLE_);
+ __declspec(dllimport) BOOL_ WINAPI
+ ResetEvent(HANDLE_);
# else
using ::SetEvent;
using ::ResetEvent;
@@ -131,14 +139,41 @@
} // extern "C"
- const DWORD_ infinite = (DWORD_)0xFFFFFFFF;
- const DWORD_ wait_abandoned = 0x00000080L;
- const DWORD_ wait_object_0 = 0x00000000L;
- const DWORD_ wait_timeout = 0x00000102L;
- const DWORD_ wait_failed = (DWORD_)0xFFFFFFFF;
+const DWORD_ infinite = (DWORD_)0xFFFFFFFF;
+const DWORD_ wait_abandoned = 0x00000080L;
+const DWORD_ wait_object_0 = 0x00000000L;
+const DWORD_ wait_timeout = 0x00000102L;
+const DWORD_ wait_failed = (DWORD_)0xFFFFFFFF;
#endif // defined( BOOST_USE_WINDOWS_H )
+BOOST_FORCEINLINE HANDLE_ create_anonymous_mutex(_SECURITY_ATTRIBUTES* lpAttributes, BOOL_ bInitialOwner)
+{
+#ifdef BOOST_NO_ANSI_APIS
+ return CreateMutexW(lpAttributes, bInitialOwner, 0);
+#else
+ return CreateMutexA(lpAttributes, bInitialOwner, 0);
+#endif
+}
+
+BOOST_FORCEINLINE HANDLE_ create_anonymous_semaphore(_SECURITY_ATTRIBUTES* lpAttributes, LONG_ lInitialCount, LONG_ lMaximumCount)
+{
+#ifdef BOOST_NO_ANSI_APIS
+ return CreateSemaphoreW(lpAttributes, lInitialCount, lMaximumCount, 0);
+#else
+ return CreateSemaphoreA(lpAttributes, lInitialCount, lMaximumCount, 0);
+#endif
+}
+
+BOOST_FORCEINLINE HANDLE_ create_anonymous_event(_SECURITY_ATTRIBUTES* lpAttributes, BOOL_ bManualReset, BOOL_ bInitialState)
+{
+#ifdef BOOST_NO_ANSI_APIS
+ return CreateEventW(lpAttributes, bManualReset, bInitialState, 0);
+#else
+ return CreateEventA(lpAttributes, bManualReset, bInitialState, 0);
+#endif
+}
+
}
}
}
Modified: trunk/boost/detail/winapi/thread.hpp
==============================================================================
--- trunk/boost/detail/winapi/thread.hpp Sun Oct 6 13:12:46 2013 (r86178)
+++ trunk/boost/detail/winapi/thread.hpp 2013-10-06 13:40:19 EDT (Sun, 06 Oct 2013) (r86179)
@@ -26,21 +26,21 @@
using ::GetCurrentThreadId;
using ::SleepEx;
using ::Sleep;
+ using ::SwitchToThread;
#else
-extern "C" {
+extern "C" {
# ifndef UNDER_CE
- __declspec(dllimport) unsigned long __stdcall
- GetCurrentThreadId(void);
- __declspec(dllimport) unsigned long __stdcall
- SleepEx(unsigned long,int);
- __declspec(dllimport) void __stdcall
- Sleep(unsigned long);
+ __declspec(dllimport) DWORD_ WINAPI GetCurrentThreadId(void);
+ __declspec(dllimport) DWORD_ WINAPI SleepEx(DWORD_, BOOL_);
+ __declspec(dllimport) void WINAPI Sleep(DWORD_);
+ __declspec(dllimport) BOOL_ WINAPI SwitchToThread(void);
#else
using ::GetCurrentThreadId;
using ::SleepEx;
using ::Sleep;
-#endif
-}
+ using ::SwitchToThread;
+#endif
+}
#endif
}
}
Added: trunk/boost/detail/winapi/thread_pool.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/detail/winapi/thread_pool.hpp 2013-10-06 13:40:19 EDT (Sun, 06 Oct 2013) (r86179)
@@ -0,0 +1,102 @@
+// thread_pool.hpp --------------------------------------------------------------//
+
+// Copyright 2013 Andrey Semashev
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+
+#ifndef BOOST_DETAIL_WINAPI_THREAD_POOL_HPP
+#define BOOST_DETAIL_WINAPI_THREAD_POOL_HPP
+
+#include <boost/detail/winapi/basic_types.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost
+{
+namespace detail
+{
+namespace winapi
+{
+#if defined( BOOST_USE_WINDOWS_H )
+
+typedef ::WAITORTIMERCALLBACKFUNC WAITORTIMERCALLBACKFUNC_;
+typedef ::WAITORTIMERCALLBACK WAITORTIMERCALLBACK_;
+
+using ::RegisterWaitForSingleObject;
+using ::RegisterWaitForSingleObjectEx;
+using ::UnregisterWait;
+using ::UnregisterWaitEx;
+
+const ULONG_ wt_execute_default = WT_EXECUTEDEFAULT;
+const ULONG_ wt_execute_in_io_thread = WT_EXECUTEINIOTHREAD;
+const ULONG_ wt_execute_in_ui_thread = WT_EXECUTEINUITHREAD;
+const ULONG_ wt_execute_in_wait_thread = WT_EXECUTEINWAITTHREAD;
+const ULONG_ wt_execute_only_once = WT_EXECUTEONLYONCE;
+const ULONG_ wt_execute_in_timer_thread = WT_EXECUTEINTIMERTHREAD;
+const ULONG_ wt_execute_long_function = WT_EXECUTELONGFUNCTION;
+const ULONG_ wt_execute_in_persistent_io_thread = WT_EXECUTEINPERSISTENTIOTHREAD;
+const ULONG_ wt_execute_in_persistent_thread = WT_EXECUTEINPERSISTENTTHREAD;
+const ULONG_ wt_transfer_impersonation = WT_TRANSFER_IMPERSONATION;
+
+inline ULONG_ wt_set_max_threadpool_threads(ULONG_ flags, ULONG_ limit)
+{
+ return WT_SET_MAX_THREADPOOL_THREADS(flags, limit);
+}
+
+#else
+
+extern "C" {
+
+typedef void (NTAPI* WAITORTIMERCALLBACKFUNC_) (PVOID_, BOOLEAN_);
+typedef WAITORTIMERCALLBACKFUNC_ WAITORTIMERCALLBACK_;
+
+__declspec(dllimport) BOOL_ WINAPI RegisterWaitForSingleObject
+(
+ HANDLE_* phNewWaitObject,
+ HANDLE_ hObject,
+ WAITORTIMERCALLBACK_ Callback,
+ PVOID_ Context,
+ ULONG_ dwMilliseconds,
+ ULONG_ dwFlags
+);
+
+__declspec(dllimport) HANDLE_ WINAPI RegisterWaitForSingleObjectEx
+(
+ HANDLE_ hObject,
+ WAITORTIMERCALLBACK_ Callback,
+ PVOID_ Context,
+ ULONG_ dwMilliseconds,
+ ULONG_ dwFlags
+);
+
+__declspec(dllimport) BOOL_ WINAPI UnregisterWait(HANDLE_ WaitHandle);
+__declspec(dllimport) BOOL_ WINAPI UnregisterWaitEx(HANDLE_ WaitHandle, HANDLE_ CompletionEvent);
+
+} // extern "C"
+
+const ULONG_ wt_execute_default = 0x00000000;
+const ULONG_ wt_execute_in_io_thread = 0x00000001;
+const ULONG_ wt_execute_in_ui_thread = 0x00000002;
+const ULONG_ wt_execute_in_wait_thread = 0x00000004;
+const ULONG_ wt_execute_only_once = 0x00000008;
+const ULONG_ wt_execute_in_timer_thread = 0x00000020;
+const ULONG_ wt_execute_long_function = 0x00000010;
+const ULONG_ wt_execute_in_persistent_io_thread = 0x00000040;
+const ULONG_ wt_execute_in_persistent_thread = 0x00000080;
+const ULONG_ wt_transfer_impersonation = 0x00000100;
+
+inline ULONG_ wt_set_max_threadpool_threads(ULONG_ flags, ULONG_ limit)
+{
+ return flags | (limit << 16);
+}
+
+#endif
+}
+}
+}
+
+#endif // BOOST_DETAIL_WINAPI_THREAD_POOL_HPP
Added: trunk/boost/detail/winapi/tls.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/detail/winapi/tls.hpp 2013-10-06 13:40:19 EDT (Sun, 06 Oct 2013) (r86179)
@@ -0,0 +1,49 @@
+// tls.hpp --------------------------------------------------------------//
+
+// Copyright 2013 Andrey Semashev
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+
+#ifndef BOOST_DETAIL_WINAPI_TLS_HPP
+#define BOOST_DETAIL_WINAPI_TLS_HPP
+
+#include <boost/detail/winapi/basic_types.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost
+{
+namespace detail
+{
+namespace winapi
+{
+#if defined( BOOST_USE_WINDOWS_H )
+
+using ::TlsAlloc;
+using ::TlsGetValue;
+using ::TlsSetValue;
+using ::TlsFree;
+
+const DWORD_ tls_out_of_indexes = TLS_OUT_OF_INDEXES;
+
+#else
+
+extern "C" {
+__declspec(dllimport) DWORD_ WINAPI TlsAlloc(void);
+__declspec(dllimport) LPVOID_ WINAPI TlsGetValue(DWORD_ dwTlsIndex);
+__declspec(dllimport) BOOL_ WINAPI TlsSetValue(DWORD_ dwTlsIndex, LPVOID_ lpTlsValue);
+__declspec(dllimport) BOOL_ WINAPI TlsFree(DWORD_ dwTlsIndex);
+}
+
+const DWORD_ tls_out_of_indexes = 0xFFFFFFFF;
+
+#endif
+}
+}
+}
+
+#endif // BOOST_DETAIL_WINAPI_TLS_HPP
Added: trunk/boost/detail/winapi/waitable_timer.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/detail/winapi/waitable_timer.hpp 2013-10-06 13:40:19 EDT (Sun, 06 Oct 2013) (r86179)
@@ -0,0 +1,110 @@
+// waitable_timer.hpp --------------------------------------------------------------//
+
+// Copyright 2013 Andrey Semashev
+
+// Distributed under the Boost Software License, Version 1.0.
+// See http://www.boost.org/LICENSE_1_0.txt
+
+
+#ifndef BOOST_DETAIL_WINAPI_WAITABLE_TIMER_HPP
+#define BOOST_DETAIL_WINAPI_WAITABLE_TIMER_HPP
+
+#include <boost/detail/winapi/basic_types.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost
+{
+namespace detail
+{
+namespace winapi
+{
+#if defined( BOOST_USE_WINDOWS_H )
+
+typedef ::PTIMERAPCROUTINE PTIMERAPCROUTINE_;
+
+# ifdef BOOST_NO_ANSI_APIS
+using ::CreateWaitableTimerW;
+using ::OpenWaitableTimerW;
+# else
+using ::CreateWaitableTimerA;
+using ::OpenWaitableTimerA;
+# endif
+using ::SetWaitableTimer;
+using ::CancelWaitableTimer;
+
+#else
+
+extern "C" {
+
+struct _SECURITY_ATTRIBUTES;
+
+typedef void (WINAPI* PTIMERAPCROUTINE_)
+(
+ LPVOID_ lpArgToCompletionRoutine,
+ DWORD_ dwTimerLowValue,
+ DWORD_ dwTimerHighValue
+);
+
+# ifdef BOOST_NO_ANSI_APIS
+__declspec(dllimport) HANDLE_ WINAPI CreateWaitableTimerW
+(
+ _SECURITY_ATTRIBUTES* lpTimerAttributes,
+ BOOL_ bManualReset,
+ LPCWSTR_ lpTimerName
+);
+
+__declspec(dllimport) HANDLE_ WINAPI OpenWaitableTimerW
+(
+ DWORD_ dwDesiredAccess,
+ BOOL_ bInheritHandle,
+ LPCWSTR_ lpTimerName
+);
+# else
+__declspec(dllimport) HANDLE_ WINAPI CreateWaitableTimerA
+(
+ _SECURITY_ATTRIBUTES* lpTimerAttributes,
+ BOOL_ bManualReset,
+ LPCSTR_ lpTimerName
+);
+
+__declspec(dllimport) HANDLE_ WINAPI OpenWaitableTimerA
+(
+ DWORD_ dwDesiredAccess,
+ BOOL_ bInheritHandle,
+ LPCSTR_ lpTimerName
+);
+# endif
+
+__declspec(dllimport) BOOL_ WINAPI SetWaitableTimer
+(
+ HANDLE_ hTimer,
+ const LARGE_INTEGER_ *lpDueTime,
+ LONG_ lPeriod,
+ PTIMERAPCROUTINE_ pfnCompletionRoutine,
+ LPVOID_ lpArgToCompletionRoutine,
+ BOOL_ fResume
+);
+
+__declspec(dllimport) BOOL_ WINAPI CancelWaitableTimer(HANDLE_ hTimer);
+
+}
+
+#endif
+
+BOOST_FORCEINLINE HANDLE_ create_anonymous_waitable_timer(_SECURITY_ATTRIBUTES* lpTimerAttributes, BOOL_ bManualReset)
+{
+#ifdef BOOST_NO_ANSI_APIS
+ return CreateWaitableTimerW(lpTimerAttributes, bManualReset, 0);
+#else
+ return CreateWaitableTimerA(lpTimerAttributes, bManualReset, 0);
+#endif
+}
+
+}
+}
+}
+
+#endif // BOOST_DETAIL_WINAPI_WAITABLE_TIMER_HPP
Modified: trunk/boost/sync/detail/condition_variables/basic_condition_variable_windows.hpp
==============================================================================
--- trunk/boost/sync/detail/condition_variables/basic_condition_variable_windows.hpp Sun Oct 6 13:12:46 2013 (r86178)
+++ trunk/boost/sync/detail/condition_variables/basic_condition_variable_windows.hpp 2013-10-06 13:40:19 EDT (Sun, 06 Oct 2013) (r86179)
@@ -34,7 +34,6 @@
#include <boost/sync/detail/time_units.hpp>
#include <boost/sync/detail/interlocked.hpp>
#include <boost/sync/detail/auto_handle.hpp>
-#include <boost/sync/detail/windows_primitives.hpp>
#include <boost/sync/locks/lock_guard.hpp>
#include <boost/sync/mutexes/mutex.hpp>
#include <boost/sync/condition_variables/cv_status.hpp>
@@ -63,7 +62,7 @@
public:
explicit cv_list_entry(auto_handle const& wake_sem):
- m_semaphore(create_anonymous_semaphore(0, LONG_MAX)),
+ m_semaphore(boost::detail::winapi::create_anonymous_semaphore(0, LONG_MAX)),
m_wake_sem(wake_sem.duplicate()),
m_waiters(1),
m_notified(false)
@@ -72,7 +71,7 @@
BOOST_THROW_EXCEPTION(resource_error("boost::sync::condition_variable: failed to create a semaphore"));
}
- static bool no_waiters(boost::intrusive_ptr< cv_list_entry > const& entry)
+ static bool no_waiters(intrusive_ptr< cv_list_entry > const& entry)
{
return interlocked_read_acquire(&entry->m_waiters) == 0;
}
@@ -307,7 +306,7 @@
if(!m_wake_sem)
{
- m_wake_sem = create_anonymous_semaphore(0, LONG_MAX);
+ m_wake_sem = boost::detail::winapi::create_anonymous_semaphore(0, LONG_MAX);
BOOST_ASSERT(m_wake_sem);
}
Modified: trunk/boost/sync/detail/event/event_windows.hpp
==============================================================================
--- trunk/boost/sync/detail/event/event_windows.hpp Sun Oct 6 13:12:46 2013 (r86178)
+++ trunk/boost/sync/detail/event/event_windows.hpp 2013-10-06 13:40:19 EDT (Sun, 06 Oct 2013) (r86179)
@@ -38,7 +38,7 @@
public:
explicit win32_event_base(bool auto_reset)
{
- handle_ = boost::detail::winapi::CreateEventA(NULL, !auto_reset, 0, NULL);
+ handle_ = boost::detail::winapi::create_anonymous_event(NULL, !auto_reset, 0);
if (!handle_)
{
const DWORD_ err = boost::detail::winapi::GetLastError();
@@ -142,33 +142,33 @@
{
public:
auto_reset_event() : win32_event_base(true) {}
-
+
void post() { win32_event_base::post(); }
void wait() { win32_event_base::wait(); }
bool try_wait() { return win32_event_base::try_wait(); }
template <typename Duration>
- bool try_wait_for(const Duration & duration) { return win32_event_base::try_wait_for( duration ); }
+ bool try_wait_for(const Duration & duration) { return win32_event_base::try_wait_for( duration ); }
template <typename TimePoint>
- bool try_wait_until(const TimePoint & timeout) { return win32_event_base::try_wait_until( timeout ); }
+ bool try_wait_until(const TimePoint & timeout) { return win32_event_base::try_wait_until( timeout ); }
};
class manual_reset_event : win32_event_base
{
public:
manual_reset_event() : win32_event_base(false) {}
-
+
void post() { win32_event_base::post(); }
void wait() { win32_event_base::wait(); }
bool try_wait() { return win32_event_base::try_wait(); }
void reset() { win32_event_base::reset(); }
template <typename Duration>
- bool try_wait_for(const Duration & duration) { return win32_event_base::try_wait_for( duration ); }
+ bool try_wait_for(const Duration & duration) { return win32_event_base::try_wait_for( duration ); }
template <typename TimePoint>
- bool try_wait_until(const TimePoint & timeout) { return win32_event_base::try_wait_until( timeout ); }
+ bool try_wait_until(const TimePoint & timeout) { return win32_event_base::try_wait_until( timeout ); }
};
Added: trunk/boost/sync/detail/waitable_timer.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/sync/detail/waitable_timer.hpp 2013-10-06 13:40:19 EDT (Sun, 06 Oct 2013) (r86179)
@@ -0,0 +1,345 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * (C) Copyright 2013 Andrey Semashev
+ */
+/*!
+ * \file waitable_timer.hpp
+ *
+ * \brief This header is the Boost.Sync library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/sync/doc/html/index.html.
+ */
+
+#ifndef BOOST_SYNC_DETAIL_WAITABLE_TIMER_HPP_INCLUDED_
+#define BOOST_SYNC_DETAIL_WAITABLE_TIMER_HPP_INCLUDED_
+
+#include <winerror.h>
+#include <limits.h>
+#include <cstddef>
+#include <cstdlib>
+#include <stdexcept>
+#include <boost/cstdint.hpp>
+#include <boost/version.hpp>
+#include <boost/throw_exception.hpp>
+#include <boost/detail/winapi/dll.hpp>
+#include <boost/detail/winapi/tls.hpp>
+#include <boost/detail/winapi/process.hpp>
+#include <boost/detail/winapi/handles.hpp>
+#include <boost/detail/winapi/thread.hpp>
+#include <boost/detail/winapi/thread_pool.hpp>
+#include <boost/detail/winapi/waitable_timer.hpp>
+#include <boost/detail/winapi/synchronization.hpp>
+#include <boost/detail/winapi/GetLastError.hpp>
+#include <boost/sync/detail/config.hpp>
+#include <boost/sync/detail/interlocked.hpp>
+#include <boost/sync/detail/weak_linkage.hpp>
+#include <boost/sync/exceptions/resource_error.hpp>
+#include <boost/sync/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+namespace sync {
+
+namespace detail {
+
+namespace windows {
+
+/*!
+ * \brief Global waitable timer state.
+ *
+ * The implementation ensures that every thread that requests a waitable timer receives its own timer handle. The handle
+ * is created only once per thread and is kept in the thread-local storage. On the first request, the storage is initialized
+ * with a pointer to \c thread_local_context, and a wait job is registered so that the context is deleted when the requesting thread
+ * terminates.
+ *
+ * Furthermore, in order to make sure the TLS is process-wide (not just specific to a current module), we allocate a process-specific
+ * semaphore and store the TLS key as its counter. This allows to allocate only one TLS slot for the whole process.
+ *
+ * The code for getting the semaphore counter is based on Boost.Interprocess by Ion Gaztanaga and the following link:
+ * http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Semaphore/NtQuerySemaphore.html
+ */
+struct waitable_timer_state
+{
+ enum init_state
+ {
+ st_uninitialized = 0,
+ st_in_progress,
+ st_initialized
+ };
+
+ long initialized;
+ boost::detail::winapi::DWORD_ tls_key;
+ boost::detail::winapi::HANDLE_ tls_key_holder;
+
+ struct thread_local_context
+ {
+ const uint32_t boost_version; // for ABI compatibility control
+ boost::detail::winapi::HANDLE_ waitable_timer;
+ boost::detail::winapi::HANDLE_ current_thread;
+ boost::detail::winapi::HANDLE_ wait_handle;
+
+ BOOST_CONSTEXPR thread_local_context() BOOST_NOEXCEPT :
+ boost_version(BOOST_VERSION),
+ waitable_timer(NULL),
+ current_thread(NULL),
+ wait_handle(NULL)
+ {
+ }
+
+ ~thread_local_context()
+ {
+ if (wait_handle)
+ boost::detail::winapi::UnregisterWait(wait_handle);
+ if (current_thread)
+ boost::detail::winapi::CloseHandle(current_thread);
+ if (waitable_timer)
+ boost::detail::winapi::CloseHandle(waitable_timer);
+ }
+
+ static void NTAPI destroy(PVOID_ p, BOOLEAN_ /*timed_out*/)
+ {
+ delete static_cast< thread_local_context* >(p);
+ }
+
+ BOOST_DELETED_FUNCTION(thread_local_context(thread_local_context const&))
+ BOOST_DELETED_FUNCTION(thread_local_context& operator= (thread_local_context const&))
+ };
+
+ struct semaphore_basic_information
+ {
+ boost::detail::winapi::ULONG_ current_count; // current semaphore count
+ boost::detail::winapi::ULONG_ maximum_count; // max semaphore count
+ };
+
+ //! Initializes the process-wide TLS slot
+ void init()
+ {
+ while (true)
+ {
+ long old_val = BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE(&initialized, st_in_progress, st_uninitialized);
+ if (old_val == st_in_progress)
+ {
+ // Wait for another thread
+ boost::detail::winapi::SwitchToThread();
+ }
+ else if (old_val == st_initialized)
+ {
+ // Another thread completed the initialization
+ return;
+ }
+ else
+ break;
+ }
+
+ // Compose a process-specific semaphore name
+#ifndef BOOST_NO_ANSI_APIS
+ char sem_name[24] =
+#else
+ wchar_t sem_name[24] =
+#endif
+ {
+ 'b', 'o', 'o', 's', 't', '_', 's', 'y', 'n', 'c', '_', 't', 'l', 's', '_'
+ };
+ boost::detail::winapi::DWORD_ process_id = boost::detail::winapi::GetCurrentProcessId();
+ for (unsigned int i = 0; i < 4; ++i)
+ {
+ uint8_t b = static_cast< uint8_t >(process_id >> ((3u - i) * 8u));
+ uint8_t half = b >> 4;
+ if (half < 10)
+ sem_name[15 + i * 2] = '0' + half;
+ else
+ sem_name[15 + i * 2] = 'a' + half;
+
+ half = b & 0x0f;
+ if (half < 10)
+ sem_name[16 + i * 2] = '0' + half;
+ else
+ sem_name[16 + i * 2] = 'a' + half;
+ }
+ sem_name[23] = '\0';
+
+ // First try if the semaphore has already been created
+#ifndef BOOST_NO_ANSI_APIS
+ tls_key_holder = boost::detail::winapi::OpenSemaphoreA
+#else
+ tls_key_holder = boost::detail::winapi::OpenSemaphoreW
+#endif
+ (
+ 0x001F0003, // SEMAPHORE_ALL_ACCESS
+ false,
+ sem_name
+ );
+
+ if (!tls_key_holder)
+ {
+ // The semaphore is not created yet
+ boost::detail::winapi::DWORD_ key = boost::detail::winapi::TlsAlloc();
+ if (key == boost::detail::winapi::tls_out_of_indexes)
+ {
+ boost::detail::winapi::DWORD_ err = boost::detail::winapi::GetLastError();
+ BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&initialized, st_uninitialized);
+ BOOST_THROW_EXCEPTION(resource_error(err, "Boost.Sync: unable to allocate a TLS slot"));
+ }
+
+#ifndef BOOST_NO_ANSI_APIS
+ tls_key_holder = boost::detail::winapi::CreateSemaphoreA
+#else
+ tls_key_holder = boost::detail::winapi::CreateSemaphoreW
+#endif
+ (
+ NULL, key, LONG_MAX, sem_name
+ );
+
+ boost::detail::winapi::DWORD_ err = boost::detail::winapi::GetLastError();
+ if (!tls_key_holder)
+ {
+ // Cannot create a semaphore. Too bad, this will cause TLS slots to be allocated for every module.
+ tls_key = key;
+ BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&initialized, st_initialized);
+ return;
+ }
+ else if (err == ERROR_ALREADY_EXISTS)
+ {
+ // Some other thread managed to create the semaphore
+ boost::detail::winapi::TlsFree(key);
+ }
+ else
+ {
+ tls_key = key;
+ std::atexit(&waitable_timer_state::destroy);
+ BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&initialized, st_initialized);
+ return;
+ }
+ }
+
+ // Release the semaphore on process exit
+ std::atexit(&waitable_timer_state::destroy);
+
+ typedef boost::detail::winapi::DWORD_ NTSTATUS_;
+ typedef NTSTATUS_ (__stdcall *NtQuerySemaphore_t)(boost::detail::winapi::HANDLE_ h, unsigned int info_class, semaphore_basic_information* pinfo, boost::detail::winapi::ULONG_ info_size, boost::detail::winapi::ULONG_* ret_len);
+
+ // Retrieve the TLS key from the semaphore
+ NtQuerySemaphore_t nt_query_semaphore = (NtQuerySemaphore_t)boost::detail::winapi::GetProcAddress(boost::detail::winapi::GetModuleHandleA("ntdll.dll"), "NtQuerySemaphore");
+ if (nt_query_semaphore)
+ {
+ semaphore_basic_information info = {};
+ NTSTATUS_ err = nt_query_semaphore(tls_key_holder, 0 /* SemaphoreBasicInformation */, &info, sizeof(info), NULL);
+ if (err == 0)
+ {
+ tls_key = info.current_count;
+ BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&initialized, st_initialized);
+ return;
+ }
+ else
+ {
+ BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&initialized, st_uninitialized);
+ BOOST_THROW_EXCEPTION(resource_error("Boost.Sync: unable to create a semaphore for TLS storage"));
+ }
+ }
+
+ // We failed to obtain the TLS key from the semaphore. Just allocate one already.
+ boost::detail::winapi::DWORD_ key = boost::detail::winapi::TlsAlloc();
+ if (key == boost::detail::winapi::tls_out_of_indexes)
+ {
+ boost::detail::winapi::DWORD_ err = boost::detail::winapi::GetLastError();
+ BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&initialized, st_uninitialized);
+ BOOST_THROW_EXCEPTION(resource_error(err, "Boost.Sync: unable to allocate a TLS slot"));
+ }
+
+ tls_key = key;
+ BOOST_ATOMIC_INTERLOCKED_EXCHANGE(&initialized, st_initialized);
+ }
+
+ //! Initializes the thread-specific context
+ thread_local_context* create_thread_local_context()
+ {
+ thread_local_context* ctx = new thread_local_context();
+ const boost::detail::winapi::HANDLE_ current_process = boost::detail::winapi::GetCurrentProcess();
+ boost::detail::winapi::BOOL_ res = boost::detail::winapi::DuplicateHandle
+ (
+ current_process,
+ boost::detail::winapi::GetCurrentThread(),
+ current_process,
+ &ctx->current_thread,
+ 0,
+ false,
+ boost::detail::winapi::duplicate_same_access
+ );
+ if (res)
+ {
+ res = boost::detail::winapi::RegisterWaitForSingleObject
+ (
+ &ctx->wait_handle,
+ ctx->current_thread,
+ &thread_local_context::destroy,
+ ctx,
+ boost::detail::winapi::infinite,
+ boost::detail::winapi::wt_execute_in_wait_thread | boost::detail::winapi::wt_execute_only_once
+ );
+ if (res)
+ {
+ ctx->waitable_timer = boost::detail::winapi::create_anonymous_waitable_timer(NULL, false);
+ if (ctx->waitable_timer)
+ {
+ res = boost::detail::winapi::TlsSetValue(tls_key, ctx);
+ if (res)
+ return ctx;
+ }
+ }
+ }
+
+ boost::detail::winapi::DWORD_ err = boost::detail::winapi::GetLastError();
+ delete ctx;
+ BOOST_THROW_EXCEPTION(resource_error(err, "Boost.Sync: failed to initialize a waitable timer"));
+ return NULL; // unreachable; to avoid warnings about missing return statement
+ }
+
+ //! Releases the TLS key holder semaphore handle
+ static void destroy()
+ {
+ waitable_timer_state& state = weak_linkage< waitable_timer_state >::value;
+ if (state.tls_key_holder)
+ {
+ boost::detail::winapi::CloseHandle(state.tls_key_holder);
+ state.tls_key_holder = NULL;
+ }
+ }
+};
+
+//! Returns a thread-specific handle for a waitable timer for fixed time point waits
+inline boost::detail::winapi::HANDLE_ get_waitable_timer()
+{
+ waitable_timer_state& state = weak_linkage< waitable_timer_state >::value;
+
+ if (state.initialized != waitable_timer_state::st_initialized)
+ state.init();
+
+ waitable_timer_state::thread_local_context* p =
+ static_cast< waitable_timer_state::thread_local_context* >(boost::detail::winapi::TlsGetValue(state.tls_key));
+ if (!p)
+ p = state.create_thread_local_context();
+
+ // Check that the thread local context is ABI-compatible
+ if (p->boost_version != BOOST_VERSION)
+ BOOST_THROW_EXCEPTION(std::logic_error("Boost.Sync: different Boost versions are used in the application"));
+
+ return p->waitable_timer;
+}
+
+} // namespace windows
+
+} // namespace detail
+
+} // namespace sync
+
+} // namespace boost
+
+#include <boost/sync/detail/footer.hpp>
+
+#endif // BOOST_SYNC_DETAIL_WAITABLE_TIMER_HPP_INCLUDED_
Added: trunk/boost/sync/detail/weak_linkage.hpp
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ trunk/boost/sync/detail/weak_linkage.hpp 2013-10-06 13:40:19 EDT (Sun, 06 Oct 2013) (r86179)
@@ -0,0 +1,49 @@
+/*
+ * Distributed under the Boost Software License, Version 1.0.
+ * (See accompanying file LICENSE_1_0.txt or copy at
+ * http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * (C) Copyright 2013 Andrey Semashev
+ */
+/*!
+ * \file weak_linkage.hpp
+ *
+ * \brief This header is the Boost.Sync library implementation, see the library documentation
+ * at http://www.boost.org/doc/libs/release/libs/sync/doc/html/index.html.
+ */
+
+#ifndef BOOST_SYNC_DETAIL_WEAK_LINKAGE_HPP_INCLUDED_
+#define BOOST_SYNC_DETAIL_WEAK_LINKAGE_HPP_INCLUDED_
+
+#include <boost/sync/detail/config.hpp>
+#include <boost/sync/detail/header.hpp>
+
+#ifdef BOOST_HAS_PRAGMA_ONCE
+#pragma once
+#endif
+
+namespace boost {
+
+namespace sync {
+
+namespace detail {
+
+//! The template creates a module-wide global value
+template< typename T, typename Tag = void >
+struct weak_linkage
+{
+ static T value;
+};
+
+template< typename T, typename Tag >
+T weak_linkage< T, Tag >::value = {};
+
+} // namespace detail
+
+} // namespace sync
+
+} // namespace boost
+
+#include <boost/sync/detail/footer.hpp>
+
+#endif // BOOST_SYNC_DETAIL_WEAK_LINKAGE_HPP_INCLUDED_
Deleted: trunk/boost/sync/detail/windows_primitives.hpp
==============================================================================
--- trunk/boost/sync/detail/windows_primitives.hpp 2013-10-06 13:40:19 EDT (Sun, 06 Oct 2013) (r86178)
+++ /dev/null 00:00:00 1970 (deleted)
@@ -1,65 +0,0 @@
-/*
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE_1_0.txt or copy at
- * http://www.boost.org/LICENSE_1_0.txt)
- *
- * (C) Copyright 2005-2007 Anthony Williams
- * (C) Copyright 2007 David Deakins
- * (C) Copyright 2013 Andrey Semashev
- */
-/*!
- * \file windows_primitives.hpp
- *
- * \brief This header is the Boost.Sync library implementation, see the library documentation
- * at http://www.boost.org/doc/libs/release/libs/sync/doc/html/index.html.
- */
-
-#ifndef BOOST_SYNC_DETAIL_WINDOWS_PRIMITIVES_HPP_INCLUDED_
-#define BOOST_SYNC_DETAIL_WINDOWS_PRIMITIVES_HPP_INCLUDED_
-
-#include <cstddef>
-#include <boost/detail/winapi/synchronization.hpp>
-#include <boost/sync/detail/config.hpp>
-#include <boost/sync/detail/header.hpp>
-
-#ifdef BOOST_HAS_PRAGMA_ONCE
-#pragma once
-#endif
-
-namespace boost {
-
-namespace sync {
-
-namespace detail {
-
-namespace windows {
-
-BOOST_FORCEINLINE boost::detail::winapi::HANDLE_ create_anonymous_event(bool manual_reset, bool initial_state)
-{
-#if !defined(BOOST_NO_ANSI_APIS)
- return boost::detail::winapi::CreateEventA(NULL, manual_reset, initial_state, NULL);
-#else
- return boost::detail::winapi::CreateEventW(NULL, manual_reset, initial_state, NULL);
-#endif
-}
-
-BOOST_FORCEINLINE boost::detail::winapi::HANDLE_ create_anonymous_semaphore(long initial_count, long max_count)
-{
-#if !defined(BOOST_NO_ANSI_APIS)
- return CreateSemaphoreA(NULL, initial_count, max_count, NULL);
-#else
- return CreateSemaphoreW(NULL, initial_count, max_count, NULL);
-#endif
-}
-
-} // namespace windows
-
-} // namespace detail
-
-} // namespace sync
-
-} // namespace boost
-
-#include <boost/sync/detail/footer.hpp>
-
-#endif // BOOST_SYNC_DETAIL_WINDOWS_PRIMITIVES_HPP_INCLUDED_
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk