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
# endif
# endif
# ifndef NTAPI
# define NTAPI __stdcall
# endif
#else
# error "Win32 functions not available"
#endif
@@ -44,11 +47,19 @@ namespace detail {
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 @@ namespace winapi {
#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 @@ extern "C" {
// @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

View File

@@ -23,33 +23,47 @@ namespace detail
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

View File

@@ -23,10 +23,9 @@ namespace winapi {
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

View File

@@ -74,56 +74,64 @@ extern "C" {
#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" {
} // 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
}
}
}
}

View File

@@ -26,21 +26,21 @@ namespace winapi
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
}
}

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