synch.h (15103B)
1/** 2 * WinPR: Windows Portable Runtime 3 * Synchronization Functions 4 * 5 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com> 6 * Copyright 2014 Thincast Technologies GmbH 7 * Copyright 2014 Norbert Federa <norbert.federa@thincast.com> 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 22#ifndef WINPR_SYNCH_H 23#define WINPR_SYNCH_H 24 25#include <stdio.h> 26#include <stdlib.h> 27#include <string.h> 28 29#include <winpr/winpr.h> 30#include <winpr/wtypes.h> 31#include <winpr/error.h> 32#include <winpr/handle.h> 33 34#include <winpr/nt.h> 35 36#ifdef __cplusplus 37extern "C" 38{ 39#endif 40 41#ifndef _WIN32 42 43/* Mutex */ 44#define CREATE_MUTEX_INITIAL_OWNER 0x00000001 45 46 WINPR_API HANDLE CreateMutexA(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, 47 LPCSTR lpName); 48 WINPR_API HANDLE CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, 49 LPCWSTR lpName); 50 51 WINPR_API HANDLE CreateMutexExA(LPSECURITY_ATTRIBUTES lpMutexAttributes, LPCSTR lpName, 52 DWORD dwFlags, DWORD dwDesiredAccess); 53 WINPR_API HANDLE CreateMutexExW(LPSECURITY_ATTRIBUTES lpMutexAttributes, LPCWSTR lpName, 54 DWORD dwFlags, DWORD dwDesiredAccess); 55 56 WINPR_API HANDLE OpenMutexA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName); 57 WINPR_API HANDLE OpenMutexW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName); 58 59 WINPR_API BOOL ReleaseMutex(HANDLE hMutex); 60 61#ifdef UNICODE 62#define CreateMutex CreateMutexW 63#define CreateMutexEx CreateMutexExW 64#define OpenMutex OpenMutexW 65#else 66#define CreateMutex CreateMutexA 67#define CreateMutexEx CreateMutexExA 68#define OpenMutex OpenMutexA 69#endif 70 71 /* Semaphore */ 72 73 WINPR_API HANDLE CreateSemaphoreA(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, 74 LONG lInitialCount, LONG lMaximumCount, LPCSTR lpName); 75 WINPR_API HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, 76 LONG lInitialCount, LONG lMaximumCount, LPCWSTR lpName); 77 78 WINPR_API HANDLE OpenSemaphoreA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName); 79 WINPR_API HANDLE OpenSemaphoreW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName); 80 81#ifdef UNICODE 82#define CreateSemaphore CreateSemaphoreW 83#define OpenSemaphore OpenSemaphoreW 84#else 85#define CreateSemaphore CreateSemaphoreA 86#define OpenSemaphore OpenSemaphoreA 87#endif 88 89 WINPR_API BOOL ReleaseSemaphore(HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount); 90 91/* Event */ 92#define CREATE_EVENT_MANUAL_RESET 0x00000001 93#define CREATE_EVENT_INITIAL_SET 0x00000002 94 95 WINPR_API HANDLE CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, 96 BOOL bInitialState, LPCSTR lpName); 97 WINPR_API HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, 98 BOOL bInitialState, LPCWSTR lpName); 99 100 WINPR_API HANDLE CreateEventExA(LPSECURITY_ATTRIBUTES lpEventAttributes, LPCSTR lpName, 101 DWORD dwFlags, DWORD dwDesiredAccess); 102 WINPR_API HANDLE CreateEventExW(LPSECURITY_ATTRIBUTES lpEventAttributes, LPCWSTR lpName, 103 DWORD dwFlags, DWORD dwDesiredAccess); 104 105 WINPR_API HANDLE OpenEventA(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCSTR lpName); 106 WINPR_API HANDLE OpenEventW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR lpName); 107 108 WINPR_API BOOL SetEvent(HANDLE hEvent); 109 WINPR_API BOOL ResetEvent(HANDLE hEvent); 110 111#ifdef UNICODE 112#define CreateEvent CreateEventW 113#define CreateEventEx CreateEventExW 114#define OpenEvent OpenEventW 115#else 116#define CreateEvent CreateEventA 117#define CreateEventEx CreateEventExA 118#define OpenEvent OpenEventA 119#endif 120 121 /* Condition Variable */ 122 123 typedef PVOID RTL_CONDITION_VARIABLE; 124 typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE; 125 126 /* Critical Section */ 127 128 typedef struct _RTL_CRITICAL_SECTION 129 { 130 PVOID DebugInfo; 131 LONG LockCount; 132 LONG RecursionCount; 133 HANDLE OwningThread; 134 HANDLE LockSemaphore; 135 ULONG_PTR SpinCount; 136 } RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION; 137 138 typedef RTL_CRITICAL_SECTION CRITICAL_SECTION; 139 typedef PRTL_CRITICAL_SECTION PCRITICAL_SECTION; 140 typedef PRTL_CRITICAL_SECTION LPCRITICAL_SECTION; 141 142 WINPR_API VOID InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection); 143 WINPR_API BOOL InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection, 144 DWORD dwSpinCount, DWORD Flags); 145 WINPR_API BOOL InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION lpCriticalSection, 146 DWORD dwSpinCount); 147 148 WINPR_API DWORD SetCriticalSectionSpinCount(LPCRITICAL_SECTION lpCriticalSection, 149 DWORD dwSpinCount); 150 151 WINPR_API VOID EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection); 152 WINPR_API BOOL TryEnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection); 153 154 WINPR_API VOID LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection); 155 156 WINPR_API VOID DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection); 157 158 /* Sleep */ 159 160 WINPR_API VOID Sleep(DWORD dwMilliseconds); 161 WINPR_API DWORD SleepEx(DWORD dwMilliseconds, BOOL bAlertable); 162 163 /* Address */ 164 165 WINPR_API VOID WakeByAddressAll(PVOID Address); 166 WINPR_API VOID WakeByAddressSingle(PVOID Address); 167 168 WINPR_API BOOL WaitOnAddress(VOID volatile* Address, PVOID CompareAddress, SIZE_T AddressSize, 169 DWORD dwMilliseconds); 170 171 /* Wait */ 172 173#define INFINITE 0xFFFFFFFF 174 175#define WAIT_OBJECT_0 0x00000000L 176#define WAIT_ABANDONED 0x00000080L 177#define WAIT_IO_COMPLETION 0x000000C0L 178 179#ifndef WAIT_TIMEOUT 180#define WAIT_TIMEOUT 0x00000102L 181#endif 182 183#define WAIT_FAILED ((DWORD)0xFFFFFFFF) 184 185#define MAXIMUM_WAIT_OBJECTS 64 186 187 WINPR_API DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds); 188 WINPR_API DWORD WaitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertable); 189 WINPR_API DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, 190 DWORD dwMilliseconds); 191 WINPR_API DWORD WaitForMultipleObjectsEx(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, 192 DWORD dwMilliseconds, BOOL bAlertable); 193 194 WINPR_API DWORD SignalObjectAndWait(HANDLE hObjectToSignal, HANDLE hObjectToWaitOn, 195 DWORD dwMilliseconds, BOOL bAlertable); 196 197 /* Waitable Timer */ 198 199#define CREATE_WAITABLE_TIMER_MANUAL_RESET 0x00000001 200 201 typedef struct _REASON_CONTEXT 202 { 203 ULONG Version; 204 DWORD Flags; 205 206 union 207 { 208 struct 209 { 210 HMODULE LocalizedReasonModule; 211 ULONG LocalizedReasonId; 212 ULONG ReasonStringCount; 213 LPWSTR* ReasonStrings; 214 } Detailed; 215 216 LPWSTR SimpleReasonString; 217 } Reason; 218 } REASON_CONTEXT, *PREASON_CONTEXT; 219 220 typedef VOID (*PTIMERAPCROUTINE)(LPVOID lpArgToCompletionRoutine, DWORD dwTimerLowValue, 221 DWORD dwTimerHighValue); 222 223 WINPR_API HANDLE CreateWaitableTimerA(LPSECURITY_ATTRIBUTES lpTimerAttributes, 224 BOOL bManualReset, LPCSTR lpTimerName); 225 WINPR_API HANDLE CreateWaitableTimerW(LPSECURITY_ATTRIBUTES lpTimerAttributes, 226 BOOL bManualReset, LPCWSTR lpTimerName); 227 228 WINPR_API HANDLE CreateWaitableTimerExA(LPSECURITY_ATTRIBUTES lpTimerAttributes, 229 LPCSTR lpTimerName, DWORD dwFlags, 230 DWORD dwDesiredAccess); 231 WINPR_API HANDLE CreateWaitableTimerExW(LPSECURITY_ATTRIBUTES lpTimerAttributes, 232 LPCWSTR lpTimerName, DWORD dwFlags, 233 DWORD dwDesiredAccess); 234 235 WINPR_API BOOL SetWaitableTimer(HANDLE hTimer, const LARGE_INTEGER* lpDueTime, LONG lPeriod, 236 PTIMERAPCROUTINE pfnCompletionRoutine, 237 LPVOID lpArgToCompletionRoutine, BOOL fResume); 238 239 WINPR_API BOOL SetWaitableTimerEx(HANDLE hTimer, const LARGE_INTEGER* lpDueTime, LONG lPeriod, 240 PTIMERAPCROUTINE pfnCompletionRoutine, 241 LPVOID lpArgToCompletionRoutine, PREASON_CONTEXT WakeContext, 242 ULONG TolerableDelay); 243 244 WINPR_API HANDLE OpenWaitableTimerA(DWORD dwDesiredAccess, BOOL bInheritHandle, 245 LPCSTR lpTimerName); 246 WINPR_API HANDLE OpenWaitableTimerW(DWORD dwDesiredAccess, BOOL bInheritHandle, 247 LPCWSTR lpTimerName); 248 249 WINPR_API BOOL CancelWaitableTimer(HANDLE hTimer); 250 251#ifdef UNICODE 252#define CreateWaitableTimer CreateWaitableTimerW 253#define CreateWaitableTimerEx CreateWaitableTimerExW 254#define OpenWaitableTimer OpenWaitableTimerW 255#else 256#define CreateWaitableTimer CreateWaitableTimerA 257#define CreateWaitableTimerEx CreateWaitableTimerExA 258#define OpenWaitableTimer OpenWaitableTimerA 259#endif 260 261 /** 262 * Timer-Queue Timer 263 */ 264 265#define WT_EXECUTEDEFAULT 0x00000000 266#define WT_EXECUTEINIOTHREAD 0x00000001 267#define WT_EXECUTEINUITHREAD 0x00000002 268#define WT_EXECUTEINWAITTHREAD 0x00000004 269#define WT_EXECUTEONLYONCE 0x00000008 270#define WT_EXECUTELONGFUNCTION 0x00000010 271#define WT_EXECUTEINTIMERTHREAD 0x00000020 272#define WT_EXECUTEINPERSISTENTIOTHREAD 0x00000040 273#define WT_EXECUTEINPERSISTENTTHREAD 0x00000080 274#define WT_TRANSFER_IMPERSONATION 0x00000100 275 276 typedef VOID (*WAITORTIMERCALLBACK)(PVOID lpParameter, BOOLEAN TimerOrWaitFired); 277 278 WINPR_API HANDLE CreateTimerQueue(void); 279 WINPR_API BOOL DeleteTimerQueue(HANDLE TimerQueue); 280 WINPR_API BOOL DeleteTimerQueueEx(HANDLE TimerQueue, HANDLE CompletionEvent); 281 282 WINPR_API BOOL CreateTimerQueueTimer(PHANDLE phNewTimer, HANDLE TimerQueue, 283 WAITORTIMERCALLBACK Callback, PVOID Parameter, 284 DWORD DueTime, DWORD Period, ULONG Flags); 285 WINPR_API BOOL ChangeTimerQueueTimer(HANDLE TimerQueue, HANDLE Timer, ULONG DueTime, 286 ULONG Period); 287 WINPR_API BOOL DeleteTimerQueueTimer(HANDLE TimerQueue, HANDLE Timer, HANDLE CompletionEvent); 288 289#endif 290 291#if (defined(_WIN32) && (_WIN32_WINNT < 0x0600)) 292#define InitializeCriticalSectionEx(lpCriticalSection, dwSpinCount, Flags) \ 293 InitializeCriticalSectionAndSpinCount(lpCriticalSection, dwSpinCount) 294#endif 295 296#ifndef _RTL_RUN_ONCE_DEF 297#define _RTL_RUN_ONCE_DEF 298 299#define RTL_RUN_ONCE_INIT \ 300 { \ 301 0 \ 302 } 303 304#define RTL_RUN_ONCE_CHECK_ONLY 0x00000001 305#define RTL_RUN_ONCE_ASYNC 0x00000002 306#define RTL_RUN_ONCE_INIT_FAILED 0x00000004 307 308#define RTL_RUN_ONCE_CTX_RESERVED_BITS 2 309 310 typedef struct _RTL_RUN_ONCE 311 { 312 PVOID Ptr; 313 } RTL_RUN_ONCE, *PRTL_RUN_ONCE; 314 315 typedef ULONG CALLBACK RTL_RUN_ONCE_INIT_FN(PRTL_RUN_ONCE RunOnce, PVOID Parameter, 316 PVOID* Context); 317 typedef RTL_RUN_ONCE_INIT_FN* PRTL_RUN_ONCE_INIT_FN; 318 319#endif 320 321#if (!defined(_WIN32)) || (defined(_WIN32) && (_WIN32_WINNT < 0x0600)) 322 323 /* One-Time Initialization */ 324 325#define INIT_ONCE_STATIC_INIT RTL_RUN_ONCE_INIT 326 327 typedef RTL_RUN_ONCE INIT_ONCE; 328 typedef PRTL_RUN_ONCE PINIT_ONCE; 329 typedef PRTL_RUN_ONCE LPINIT_ONCE; 330 typedef BOOL(CALLBACK* PINIT_ONCE_FN)(PINIT_ONCE InitOnce, PVOID Parameter, PVOID* Context); 331 332 WINPR_API BOOL winpr_InitOnceBeginInitialize(LPINIT_ONCE lpInitOnce, DWORD dwFlags, 333 PBOOL fPending, LPVOID* lpContext); 334 WINPR_API BOOL winpr_InitOnceComplete(LPINIT_ONCE lpInitOnce, DWORD dwFlags, LPVOID lpContext); 335 WINPR_API BOOL winpr_InitOnceExecuteOnce(PINIT_ONCE InitOnce, PINIT_ONCE_FN InitFn, 336 PVOID Parameter, LPVOID* Context); 337 WINPR_API VOID winpr_InitOnceInitialize(PINIT_ONCE InitOnce); 338 339#define InitOnceBeginInitialize winpr_InitOnceBeginInitialize 340#define InitOnceComplete winpr_InitOnceComplete 341#define InitOnceExecuteOnce winpr_InitOnceExecuteOnce 342#define InitOnceInitialize winpr_InitOnceInitialize 343#endif 344 345 /* Synchronization Barrier */ 346 347#if (!defined(_WIN32)) || (defined(_WIN32) && (_WIN32_WINNT < 0x0602) && !defined(_SYNCHAPI_H_)) 348#define WINPR_SYNCHRONIZATION_BARRIER 1 349#endif 350 351#ifdef WINPR_SYNCHRONIZATION_BARRIER 352 353 typedef struct _RTL_BARRIER 354 { 355 DWORD Reserved1; 356 DWORD Reserved2; 357 ULONG_PTR Reserved3[2]; 358 DWORD Reserved4; 359 DWORD Reserved5; 360 } RTL_BARRIER, *PRTL_BARRIER; 361 362 typedef RTL_BARRIER SYNCHRONIZATION_BARRIER; 363 typedef PRTL_BARRIER PSYNCHRONIZATION_BARRIER; 364 typedef PRTL_BARRIER LPSYNCHRONIZATION_BARRIER; 365 366#define SYNCHRONIZATION_BARRIER_FLAGS_SPIN_ONLY 0x01 367#define SYNCHRONIZATION_BARRIER_FLAGS_BLOCK_ONLY 0x02 368#define SYNCHRONIZATION_BARRIER_FLAGS_NO_DELETE 0x04 369 370 WINPR_API BOOL WINAPI winpr_InitializeSynchronizationBarrier( 371 LPSYNCHRONIZATION_BARRIER lpBarrier, LONG lTotalThreads, LONG lSpinCount); 372 WINPR_API BOOL WINAPI winpr_EnterSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier, 373 DWORD dwFlags); 374 WINPR_API BOOL WINAPI winpr_DeleteSynchronizationBarrier(LPSYNCHRONIZATION_BARRIER lpBarrier); 375 376#define InitializeSynchronizationBarrier winpr_InitializeSynchronizationBarrier 377#define EnterSynchronizationBarrier winpr_EnterSynchronizationBarrier 378#define DeleteSynchronizationBarrier winpr_DeleteSynchronizationBarrier 379 380#endif 381 382 /* Extended API */ 383 384 WINPR_API VOID USleep(DWORD dwMicroseconds); 385 386 WINPR_API HANDLE CreateFileDescriptorEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, 387 BOOL bManualReset, BOOL bInitialState, 388 int FileDescriptor, ULONG mode); 389 WINPR_API HANDLE CreateFileDescriptorEventA(LPSECURITY_ATTRIBUTES lpEventAttributes, 390 BOOL bManualReset, BOOL bInitialState, 391 int FileDescriptor, ULONG mode); 392 393 WINPR_API HANDLE CreateWaitObjectEvent(LPSECURITY_ATTRIBUTES lpEventAttributes, 394 BOOL bManualReset, BOOL bInitialState, void* pObject); 395 396#ifdef UNICODE 397#define CreateFileDescriptorEvent CreateFileDescriptorEventW 398#else 399#define CreateFileDescriptorEvent CreateFileDescriptorEventA 400#endif 401 402 WINPR_API int GetEventFileDescriptor(HANDLE hEvent); 403 WINPR_API int SetEventFileDescriptor(HANDLE hEvent, int FileDescriptor, ULONG mode); 404 405 WINPR_API void* GetEventWaitObject(HANDLE hEvent); 406 407#ifdef __cplusplus 408} 409#endif 410 411#endif /* WINPR_SYNCH_H */