forked from neosmart/pevents
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwin32.cpp
135 lines (115 loc) · 3.45 KB
/
win32.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
* WIN32 Events for POSIX
* Author: Mahmoud Al-Qudsi <[email protected]>
* Copyright (C) 2011 - 2015 by NeoSmart Technologies
* This code is released under the terms of the MIT License
*/
#ifdef _WIN32
#include <Windows.h>
#include "pevents.h"
namespace neosmart
{
neosmart_event_t CreateEvent(bool manualReset, bool initialState)
{
return static_cast<neosmart_event_t>(::CreateEvent(NULL, manualReset, initialState, NULL));
}
int DestroyEvent(neosmart_event_t event)
{
HANDLE handle = static_cast<HANDLE>(event);
return CloseHandle(handle) ? 0 : GetLastError();
}
int WaitForEvent(neosmart_event_t event, uint64_t milliseconds)
{
uint32_t result = 0;
HANDLE handle = static_cast<HANDLE>(event);
//WaitForSingleObject(Ex) and WaitForMultipleObjects(Ex) only support 32-bit timeout
if (milliseconds == ((uint64_t) -1) || (milliseconds >> 32) == 0)
{
result = WaitForSingleObject(handle, static_cast<uint32_t>(milliseconds));
}
else
{
//Cannot wait for 0xFFFFFFFF because that means infinity to WIN32
uint32_t waitUnit = (INFINITE - 1);
uint64_t rounds = milliseconds / waitUnit;
uint32_t remainder = milliseconds % waitUnit;
uint32_t result = WaitForSingleObject(handle, remainder);
while (result == WAIT_TIMEOUT && rounds-- != 0)
{
result = WaitForSingleObject(handle, waitUnit);
}
}
if (result == WAIT_OBJECT_0 || result == WAIT_ABANDONED)
{
//We must swallow WAIT_ABANDONED because there is no such equivalent on *nix
return 0;
}
if (result == WAIT_TIMEOUT)
{
return WAIT_TIMEOUT;
}
return GetLastError();
}
int SetEvent(neosmart_event_t event)
{
HANDLE handle = static_cast<HANDLE>(event);
return ::SetEvent(handle) ? 0 : GetLastError();
}
int ResetEvent(neosmart_event_t event)
{
HANDLE handle = static_cast<HANDLE>(event);
return ::ResetEvent(handle) ? 0 : GetLastError();
}
#ifdef WFMO
int WaitForMultipleEvents(neosmart_event_t *events, int count, bool waitAll, uint64_t milliseconds)
{
int index = 0;
return WaitForMultipleEvents(events, count, waitAll, milliseconds, index);
}
int WaitForMultipleEvents(neosmart_event_t *events, int count, bool waitAll, uint64_t milliseconds, int &index)
{
HANDLE *handles = reinterpret_cast<HANDLE*>(events);
uint32_t result = 0;
//WaitForSingleObject(Ex) and WaitForMultipleObjects(Ex) only support 32-bit timeout
if (milliseconds == ((uint64_t) -1) || (milliseconds >> 32) == 0)
{
result = WaitForMultipleObjects(count, handles, waitAll, static_cast<uint32_t>(milliseconds));
}
else
{
//Cannot wait for 0xFFFFFFFF because that means infinity to WIN32
uint32_t waitUnit = (INFINITE - 1);
uint64_t rounds = milliseconds / waitUnit;
uint32_t remainder = milliseconds % waitUnit;
uint32_t result = WaitForMultipleObjects(count, handles, waitAll, remainder);
while (result == WAIT_TIMEOUT && rounds-- != 0)
{
result = WaitForMultipleObjects(count, handles, waitAll, waitUnit);
}
}
if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + count)
{
index = result - WAIT_OBJECT_0;
return 0;
}
else if (result >= WAIT_ABANDONED_0 && result < WAIT_ABANDONED_0 + count)
{
index = result - WAIT_ABANDONED_0;
return 0;
}
if (result == WAIT_FAILED)
{
return GetLastError();
}
return result;
}
#endif
#ifdef PULSE
int PulseEvent(neosmart_event_t event)
{
HANDLE handle = static_cast<HANDLE>(event);
return ::PulseEvent(handle) ? 0 : GetLastError();
}
#endif
}
#endif //_WIN32