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
136
137
138
139
140
141
142
143
144
|
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
136
137
|
-
+
-
+
-
-
-
+
+
-
-
+
-
+
-
-
+
-
+
-
+
-
-
+
-
+
-
+
+
-
-
+
+
-
-
+
-
+
+
-
-
+
+
-
-
+
-
-
+
-
+
-
+
-
-
-
+
+
-
-
+
|
#include <errno.h>
#import "condition.h"
#include <windows.h>
bool
int
of_condition_new(of_condition_t *condition)
{
condition->count = 0;
if ((condition->event = CreateEvent(NULL, FALSE, 0, NULL)) == NULL) {
if ((condition->event = CreateEvent(NULL, FALSE, 0, NULL)) == NULL)
errno = EAGAIN;
return false;
}
return EAGAIN;
return true;
return 0;
}
bool
int
of_condition_signal(of_condition_t *condition)
{
if (!SetEvent(condition->event)) {
switch (GetLastError()) {
case ERROR_INVALID_HANDLE:
errno = EINVAL;
return false;
return EINVAL;
default:
OF_ENSURE(0);
}
}
return true;
return 0;
}
bool
int
of_condition_broadcast(of_condition_t *condition)
{
int count = condition->count;
for (int i = 0; i < count; i++) {
if (!SetEvent(condition->event)) {
switch (GetLastError()) {
case ERROR_INVALID_HANDLE:
errno = EINVAL;
return false;
return EINVAL;
default:
OF_ENSURE(0);
}
}
}
return true;
return 0;
}
bool
int
of_condition_wait(of_condition_t *condition, of_mutex_t *mutex)
{
int error;
DWORD status;
if (!of_mutex_unlock(mutex))
return false;
if ((error = of_mutex_unlock(mutex)) != 0)
return error;
of_atomic_int_inc(&condition->count);
status = WaitForSingleObject(condition->event, INFINITE);
of_atomic_int_dec(&condition->count);
switch (status) {
case WAIT_OBJECT_0:
return of_mutex_lock(mutex);
case WAIT_FAILED:
switch (GetLastError()) {
case ERROR_INVALID_HANDLE:
errno = EINVAL;
return false;
return EINVAL;
default:
OF_ENSURE(0);
}
default:
OF_ENSURE(0);
}
}
bool
int
of_condition_timed_wait(of_condition_t *condition, of_mutex_t *mutex,
of_time_interval_t timeout)
{
int error;
DWORD status;
if (!of_mutex_unlock(mutex))
return false;
if ((error = of_mutex_unlock(mutex)) != 0)
return error;
of_atomic_int_inc(&condition->count);
status = WaitForSingleObject(condition->event, timeout * 1000);
of_atomic_int_dec(&condition->count);
switch (status) {
case WAIT_OBJECT_0:
return of_mutex_lock(mutex);
case WAIT_TIMEOUT:
errno = ETIMEDOUT;
return false;
return ETIMEDOUT;
case WAIT_FAILED:
switch (GetLastError()) {
case ERROR_INVALID_HANDLE:
errno = EINVAL;
return false;
return EINVAL;
default:
OF_ENSURE(0);
}
default:
OF_ENSURE(0);
}
}
bool
int
of_condition_free(of_condition_t *condition)
{
if (condition->count != 0) {
if (condition->count != 0)
errno = EBUSY;
return false;
}
return EBUSY;
return CloseHandle(condition->event);
return (CloseHandle(condition->event) ? 0 : EINVAL);
}
|