Boost.Sync: Added preliminary implementation of a waitable timer for fixed time point waits. Updated WinAPI functions to contain the required APIs.

[SVN r86179]
This commit is contained in:
Andrey Semashev
2013-10-06 17:40:19 +00:00
parent 4dc7897c9f
commit 933b2c596b
8 changed files with 398 additions and 64 deletions

View File

@@ -31,6 +31,9 @@
# define WINAPI __stdcall # define WINAPI __stdcall
# endif # endif
# endif # endif
# ifndef NTAPI
# define NTAPI __stdcall
# endif
#else #else
# error "Win32 functions not available" # error "Win32 functions not available"
#endif #endif
@@ -44,11 +47,19 @@ namespace detail {
namespace winapi { namespace winapi {
#if defined( BOOST_USE_WINDOWS_H ) #if defined( BOOST_USE_WINDOWS_H )
typedef ::BOOL BOOL_; typedef ::BOOL BOOL_;
typedef ::BOOLEAN BOOLEAN_;
typedef ::PBOOLEAN PBOOLEAN_;
typedef ::BYTE BYTE_;
typedef ::WORD WORD_; typedef ::WORD WORD_;
typedef ::DWORD DWORD_; typedef ::DWORD DWORD_;
typedef ::HANDLE HANDLE_; typedef ::HANDLE HANDLE_;
typedef ::HMODULE HMODULE_;
typedef ::LONG LONG_; typedef ::LONG LONG_;
typedef ::ULONG ULONG_;
typedef ::LONGLONG LONGLONG_; typedef ::LONGLONG LONGLONG_;
typedef ::INT_PTR INT_PTR_;
typedef ::UINT_PTR UINT_PTR_;
typedef ::LONG_PTR LONG_PTR_;
typedef ::ULONG_PTR ULONG_PTR_; typedef ::ULONG_PTR ULONG_PTR_;
typedef ::LARGE_INTEGER LARGE_INTEGER_; typedef ::LARGE_INTEGER LARGE_INTEGER_;
typedef ::PLARGE_INTEGER PLARGE_INTEGER_; typedef ::PLARGE_INTEGER PLARGE_INTEGER_;
@@ -63,11 +74,16 @@ namespace winapi {
#else #else
extern "C" { extern "C" {
typedef int BOOL_; typedef int BOOL_;
typedef unsigned char BYTE_;
typedef BYTE_ BOOLEAN_;
typedef BOOLEAN_* PBOOLEAN_;
typedef unsigned short WORD_; typedef unsigned short WORD_;
typedef unsigned long DWORD_; typedef unsigned long DWORD_;
typedef void* HANDLE_; typedef void* HANDLE_;
typedef void* HMODULE_;
typedef long LONG_; typedef long LONG_;
typedef unsigned long ULONG_;
// @FIXME Which condition must be tested // @FIXME Which condition must be tested
//~ #if !defined(_M_IX86) //~ #if !defined(_M_IX86)
@@ -84,11 +100,20 @@ extern "C" {
// @FIXME Which condition must be tested // @FIXME Which condition must be tested
# ifdef _WIN64 # ifdef _WIN64
#if defined(__CYGWIN__) #if defined(__CYGWIN__)
typedef long INT_PTR_;
typedef unsigned long INT_PTR_;
typedef long LONG_PTR_;
typedef unsigned long ULONG_PTR_; typedef unsigned long ULONG_PTR_;
#else #else
typedef __int64 INT_PTR_;
typedef unsigned __int64 UINT_PTR_;
typedef __int64 LONG_PTR_;
typedef unsigned __int64 ULONG_PTR_; typedef unsigned __int64 ULONG_PTR_;
#endif #endif
# else # else
typedef int INT_PTR_;
typedef unsigned int INT_PTR_;
typedef long LONG_PTR_;
typedef unsigned long ULONG_PTR_; typedef unsigned long ULONG_PTR_;
# endif # endif

View File

@@ -23,28 +23,42 @@ namespace detail
namespace winapi namespace winapi
{ {
#if defined( BOOST_USE_WINDOWS_H ) #if defined( BOOST_USE_WINDOWS_H )
typedef ::FARPROC FARPROC_;
typedef ::NEARPROC NEARPROC_;
typedef ::PROC PROC_;
using ::LoadLibrary; using ::LoadLibrary;
using ::FreeLibrary; using ::FreeLibrary;
using ::GetProcAddress; using ::GetProcAddress;
using ::GetModuleHandleA; using ::GetModuleHandleA;
#else #else
extern "C" { extern "C" {
__declspec(dllimport) HMODULE_ __stdcall #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( LoadLibrary(
LPCTSTR_ lpFileName LPCTSTR_ lpFileName
); );
__declspec(dllimport) BOOL_ __stdcall __declspec(dllimport) BOOL_ WINAPI
FreeLibrary( FreeLibrary(
HMODULE_ hModule HMODULE_ hModule
); );
__declspec(dllimport) FARPROC_ __stdcall __declspec(dllimport) FARPROC_ WINAPI
GetProcAddress( GetProcAddress(
HMODULE_ hModule, HMODULE_ hModule,
LPCSTR_ lpProcName LPCSTR_ lpProcName
); );
__declspec(dllimport) FARPROC_ __stdcall __declspec(dllimport) HMODULE_ WINAPI
GetModuleHandleA( GetModuleHandleA(
LPCSTR_ lpProcName LPCSTR_ lpFileName
); );
} }
#endif #endif
@@ -52,4 +66,4 @@ extern "C" {
} }
} }
#endif // BOOST_DETAIL_WINAPI_THREAD_HPP #endif // BOOST_DETAIL_WINAPI_DLL_HPP

View File

@@ -24,8 +24,7 @@ namespace winapi {
#else #else
# ifndef UNDER_CE # ifndef UNDER_CE
extern "C" { extern "C" {
__declspec(dllimport) unsigned long __stdcall __declspec(dllimport) DWORD_ WINAPI GetCurrentProcessId(void);
GetCurrentProcessId(void);
} }
# else # else
using ::GetCurrentProcessId; using ::GetCurrentProcessId;

View File

@@ -74,56 +74,64 @@ extern "C" {
#endif #endif
}; };
__declspec(dllimport) void __stdcall __declspec(dllimport) void WINAPI
InitializeCriticalSection(CRITICAL_SECTION_ *); InitializeCriticalSection(CRITICAL_SECTION_ *);
__declspec(dllimport) void __stdcall __declspec(dllimport) void WINAPI
EnterCriticalSection(CRITICAL_SECTION_ *); EnterCriticalSection(CRITICAL_SECTION_ *);
__declspec(dllimport) bool __stdcall __declspec(dllimport) bool WINAPI
TryEnterCriticalSection(CRITICAL_SECTION_ *); TryEnterCriticalSection(CRITICAL_SECTION_ *);
__declspec(dllimport) void __stdcall __declspec(dllimport) void WINAPI
LeaveCriticalSection(CRITICAL_SECTION_ *); LeaveCriticalSection(CRITICAL_SECTION_ *);
__declspec(dllimport) void __stdcall __declspec(dllimport) void WINAPI
DeleteCriticalSection(CRITICAL_SECTION_ *); DeleteCriticalSection(CRITICAL_SECTION_ *);
struct _SECURITY_ATTRIBUTES; struct _SECURITY_ATTRIBUTES;
# ifdef BOOST_NO_ANSI_APIS # ifdef BOOST_NO_ANSI_APIS
__declspec(dllimport) void* __stdcall __declspec(dllimport) HANDLE_ WINAPI
CreateMutexW(_SECURITY_ATTRIBUTES*,int,wchar_t const*); CreateMutexW(_SECURITY_ATTRIBUTES*, BOOL_, LPCWSTR_);
__declspec(dllimport) void* __stdcall __declspec(dllimport) HANDLE_ WINAPI
CreateSemaphoreW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*); OpenMutexW(DWORD_ dwDesiredAccess, BOOL_ bInheritHandle, LPCWSTR_ lpName);
__declspec(dllimport) void* __stdcall __declspec(dllimport) HANDLE_ WINAPI
CreateEventW(_SECURITY_ATTRIBUTES*,int,int,wchar_t const*); CreateSemaphoreW(_SECURITY_ATTRIBUTES*, LONG_, LONG_, LPCWSTR_);
__declspec(dllimport) void* __stdcall __declspec(dllimport) HANDLE_ WINAPI
OpenEventW(unsigned long,int,wchar_t const*); 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 # else
__declspec(dllimport) void* __stdcall __declspec(dllimport) HANDLE_ WINAPI
CreateMutexA(_SECURITY_ATTRIBUTES*,int,char const*); CreateMutexA(_SECURITY_ATTRIBUTES*, BOOL_, LPCSTR_);
__declspec(dllimport) void* __stdcall __declspec(dllimport) HANDLE_ WINAPI
CreateSemaphoreA(_SECURITY_ATTRIBUTES*,long,long,char const*); OpenMutexA(DWORD_ dwDesiredAccess, BOOL_ bInheritHandle, LPCSTR_ lpName);
__declspec(dllimport) void* __stdcall __declspec(dllimport) HANDLE_ WINAPI
CreateEventA(_SECURITY_ATTRIBUTES*,int,int,char const*); CreateSemaphoreA(_SECURITY_ATTRIBUTES*, LONG_, LONG_, LPCSTR_);
__declspec(dllimport) void* __stdcall __declspec(dllimport) HANDLE_ WINAPI
OpenEventA(unsigned long,int,char const*); 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 # endif
__declspec(dllimport) int __stdcall __declspec(dllimport) BOOL_ WINAPI
ReleaseMutex(void*); ReleaseMutex(HANDLE_);
__declspec(dllimport) unsigned long __stdcall __declspec(dllimport) DWORD_ WINAPI
WaitForSingleObject(void*,unsigned long); WaitForSingleObject(HANDLE_, DWORD_);
__declspec(dllimport) unsigned long __stdcall __declspec(dllimport) DWORD_ WINAPI
WaitForMultipleObjects(unsigned long nCount, WaitForMultipleObjects(DWORD_ nCount,
void* const * lpHandles, HANDLE_ const * lpHandles,
int bWaitAll, BOOL_ bWaitAll,
unsigned long dwMilliseconds); DWORD_ dwMilliseconds);
__declspec(dllimport) int __stdcall __declspec(dllimport) BOOL_ WINAPI
ReleaseSemaphore(void*,long,long*); ReleaseSemaphore(HANDLE_, LONG_, LONG_*);
typedef void (__stdcall *PAPCFUNC8)(ULONG_PTR_); typedef void (__stdcall *PAPCFUNC8)(ULONG_PTR_);
__declspec(dllimport) unsigned long __stdcall __declspec(dllimport) DWORD_ WINAPI
QueueUserAPC(PAPCFUNC8,void*,ULONG_PTR_); QueueUserAPC(PAPCFUNC8, HANDLE_, ULONG_PTR_);
# ifndef UNDER_CE # ifndef UNDER_CE
__declspec(dllimport) int __stdcall __declspec(dllimport) BOOL_ WINAPI
SetEvent(void*); SetEvent(HANDLE_);
__declspec(dllimport) int __stdcall __declspec(dllimport) BOOL_ WINAPI
ResetEvent(void*); ResetEvent(HANDLE_);
# else # else
using ::SetEvent; using ::SetEvent;
using ::ResetEvent; using ::ResetEvent;
@@ -139,6 +147,33 @@ extern "C" {
#endif // defined( BOOST_USE_WINDOWS_H ) #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
}
} }
} }
} }

View File

@@ -26,19 +26,19 @@ namespace winapi
using ::GetCurrentThreadId; using ::GetCurrentThreadId;
using ::SleepEx; using ::SleepEx;
using ::Sleep; using ::Sleep;
using ::SwitchToThread;
#else #else
extern "C" { extern "C" {
# ifndef UNDER_CE # ifndef UNDER_CE
__declspec(dllimport) unsigned long __stdcall __declspec(dllimport) DWORD_ WINAPI GetCurrentThreadId(void);
GetCurrentThreadId(void); __declspec(dllimport) DWORD_ WINAPI SleepEx(DWORD_, BOOL_);
__declspec(dllimport) unsigned long __stdcall __declspec(dllimport) void WINAPI Sleep(DWORD_);
SleepEx(unsigned long,int); __declspec(dllimport) BOOL_ WINAPI SwitchToThread(void);
__declspec(dllimport) void __stdcall
Sleep(unsigned long);
#else #else
using ::GetCurrentThreadId; using ::GetCurrentThreadId;
using ::SleepEx; using ::SleepEx;
using ::Sleep; using ::Sleep;
using ::SwitchToThread;
#endif #endif
} }
#endif #endif

View File

@@ -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

View File

@@ -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

View File

@@ -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