1*663afb9bSAndroid Build Coastguard Worker /*
2*663afb9bSAndroid Build Coastguard Worker * Copyright 2009-2012 Niels Provos and Nick Mathewson
3*663afb9bSAndroid Build Coastguard Worker *
4*663afb9bSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
5*663afb9bSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
6*663afb9bSAndroid Build Coastguard Worker * are met:
7*663afb9bSAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
8*663afb9bSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
9*663afb9bSAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
10*663afb9bSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
11*663afb9bSAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
12*663afb9bSAndroid Build Coastguard Worker * 3. The name of the author may not be used to endorse or promote products
13*663afb9bSAndroid Build Coastguard Worker * derived from this software without specific prior written permission.
14*663afb9bSAndroid Build Coastguard Worker *
15*663afb9bSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16*663afb9bSAndroid Build Coastguard Worker * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17*663afb9bSAndroid Build Coastguard Worker * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18*663afb9bSAndroid Build Coastguard Worker * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19*663afb9bSAndroid Build Coastguard Worker * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20*663afb9bSAndroid Build Coastguard Worker * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21*663afb9bSAndroid Build Coastguard Worker * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22*663afb9bSAndroid Build Coastguard Worker * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23*663afb9bSAndroid Build Coastguard Worker * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24*663afb9bSAndroid Build Coastguard Worker * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*663afb9bSAndroid Build Coastguard Worker */
26*663afb9bSAndroid Build Coastguard Worker #include "event2/event-config.h"
27*663afb9bSAndroid Build Coastguard Worker #include "evconfig-private.h"
28*663afb9bSAndroid Build Coastguard Worker
29*663afb9bSAndroid Build Coastguard Worker #ifdef _WIN32
30*663afb9bSAndroid Build Coastguard Worker #ifndef _WIN32_WINNT
31*663afb9bSAndroid Build Coastguard Worker /* Minimum required for InitializeCriticalSectionAndSpinCount */
32*663afb9bSAndroid Build Coastguard Worker #define _WIN32_WINNT 0x0403
33*663afb9bSAndroid Build Coastguard Worker #endif
34*663afb9bSAndroid Build Coastguard Worker #include <winsock2.h>
35*663afb9bSAndroid Build Coastguard Worker #define WIN32_LEAN_AND_MEAN
36*663afb9bSAndroid Build Coastguard Worker #include <windows.h>
37*663afb9bSAndroid Build Coastguard Worker #undef WIN32_LEAN_AND_MEAN
38*663afb9bSAndroid Build Coastguard Worker #include <sys/locking.h>
39*663afb9bSAndroid Build Coastguard Worker #endif
40*663afb9bSAndroid Build Coastguard Worker
41*663afb9bSAndroid Build Coastguard Worker struct event_base;
42*663afb9bSAndroid Build Coastguard Worker #include "event2/thread.h"
43*663afb9bSAndroid Build Coastguard Worker
44*663afb9bSAndroid Build Coastguard Worker #include "mm-internal.h"
45*663afb9bSAndroid Build Coastguard Worker #include "evthread-internal.h"
46*663afb9bSAndroid Build Coastguard Worker #include "time-internal.h"
47*663afb9bSAndroid Build Coastguard Worker
48*663afb9bSAndroid Build Coastguard Worker #define SPIN_COUNT 2000
49*663afb9bSAndroid Build Coastguard Worker
50*663afb9bSAndroid Build Coastguard Worker static void *
evthread_win32_lock_create(unsigned locktype)51*663afb9bSAndroid Build Coastguard Worker evthread_win32_lock_create(unsigned locktype)
52*663afb9bSAndroid Build Coastguard Worker {
53*663afb9bSAndroid Build Coastguard Worker CRITICAL_SECTION *lock = mm_malloc(sizeof(CRITICAL_SECTION));
54*663afb9bSAndroid Build Coastguard Worker if (!lock)
55*663afb9bSAndroid Build Coastguard Worker return NULL;
56*663afb9bSAndroid Build Coastguard Worker if (InitializeCriticalSectionAndSpinCount(lock, SPIN_COUNT) == 0) {
57*663afb9bSAndroid Build Coastguard Worker mm_free(lock);
58*663afb9bSAndroid Build Coastguard Worker return NULL;
59*663afb9bSAndroid Build Coastguard Worker }
60*663afb9bSAndroid Build Coastguard Worker return lock;
61*663afb9bSAndroid Build Coastguard Worker }
62*663afb9bSAndroid Build Coastguard Worker
63*663afb9bSAndroid Build Coastguard Worker static void
evthread_win32_lock_free(void * lock_,unsigned locktype)64*663afb9bSAndroid Build Coastguard Worker evthread_win32_lock_free(void *lock_, unsigned locktype)
65*663afb9bSAndroid Build Coastguard Worker {
66*663afb9bSAndroid Build Coastguard Worker CRITICAL_SECTION *lock = lock_;
67*663afb9bSAndroid Build Coastguard Worker DeleteCriticalSection(lock);
68*663afb9bSAndroid Build Coastguard Worker mm_free(lock);
69*663afb9bSAndroid Build Coastguard Worker }
70*663afb9bSAndroid Build Coastguard Worker
71*663afb9bSAndroid Build Coastguard Worker static int
evthread_win32_lock(unsigned mode,void * lock_)72*663afb9bSAndroid Build Coastguard Worker evthread_win32_lock(unsigned mode, void *lock_)
73*663afb9bSAndroid Build Coastguard Worker {
74*663afb9bSAndroid Build Coastguard Worker CRITICAL_SECTION *lock = lock_;
75*663afb9bSAndroid Build Coastguard Worker if ((mode & EVTHREAD_TRY)) {
76*663afb9bSAndroid Build Coastguard Worker return ! TryEnterCriticalSection(lock);
77*663afb9bSAndroid Build Coastguard Worker } else {
78*663afb9bSAndroid Build Coastguard Worker EnterCriticalSection(lock);
79*663afb9bSAndroid Build Coastguard Worker return 0;
80*663afb9bSAndroid Build Coastguard Worker }
81*663afb9bSAndroid Build Coastguard Worker }
82*663afb9bSAndroid Build Coastguard Worker
83*663afb9bSAndroid Build Coastguard Worker static int
evthread_win32_unlock(unsigned mode,void * lock_)84*663afb9bSAndroid Build Coastguard Worker evthread_win32_unlock(unsigned mode, void *lock_)
85*663afb9bSAndroid Build Coastguard Worker {
86*663afb9bSAndroid Build Coastguard Worker CRITICAL_SECTION *lock = lock_;
87*663afb9bSAndroid Build Coastguard Worker LeaveCriticalSection(lock);
88*663afb9bSAndroid Build Coastguard Worker return 0;
89*663afb9bSAndroid Build Coastguard Worker }
90*663afb9bSAndroid Build Coastguard Worker
91*663afb9bSAndroid Build Coastguard Worker static unsigned long
evthread_win32_get_id(void)92*663afb9bSAndroid Build Coastguard Worker evthread_win32_get_id(void)
93*663afb9bSAndroid Build Coastguard Worker {
94*663afb9bSAndroid Build Coastguard Worker return (unsigned long) GetCurrentThreadId();
95*663afb9bSAndroid Build Coastguard Worker }
96*663afb9bSAndroid Build Coastguard Worker
97*663afb9bSAndroid Build Coastguard Worker #ifdef WIN32_HAVE_CONDITION_VARIABLES
98*663afb9bSAndroid Build Coastguard Worker static void WINAPI (*InitializeConditionVariable_fn)(PCONDITION_VARIABLE)
99*663afb9bSAndroid Build Coastguard Worker = NULL;
100*663afb9bSAndroid Build Coastguard Worker static BOOL WINAPI (*SleepConditionVariableCS_fn)(
101*663afb9bSAndroid Build Coastguard Worker PCONDITION_VARIABLE, PCRITICAL_SECTION, DWORD) = NULL;
102*663afb9bSAndroid Build Coastguard Worker static void WINAPI (*WakeAllConditionVariable_fn)(PCONDITION_VARIABLE) = NULL;
103*663afb9bSAndroid Build Coastguard Worker static void WINAPI (*WakeConditionVariable_fn)(PCONDITION_VARIABLE) = NULL;
104*663afb9bSAndroid Build Coastguard Worker
105*663afb9bSAndroid Build Coastguard Worker static int
evthread_win32_condvar_init(void)106*663afb9bSAndroid Build Coastguard Worker evthread_win32_condvar_init(void)
107*663afb9bSAndroid Build Coastguard Worker {
108*663afb9bSAndroid Build Coastguard Worker HANDLE lib;
109*663afb9bSAndroid Build Coastguard Worker
110*663afb9bSAndroid Build Coastguard Worker lib = GetModuleHandle(TEXT("kernel32.dll"));
111*663afb9bSAndroid Build Coastguard Worker if (lib == NULL)
112*663afb9bSAndroid Build Coastguard Worker return 0;
113*663afb9bSAndroid Build Coastguard Worker
114*663afb9bSAndroid Build Coastguard Worker #define LOAD(name) \
115*663afb9bSAndroid Build Coastguard Worker name##_fn = GetProcAddress(lib, #name)
116*663afb9bSAndroid Build Coastguard Worker LOAD(InitializeConditionVariable);
117*663afb9bSAndroid Build Coastguard Worker LOAD(SleepConditionVariableCS);
118*663afb9bSAndroid Build Coastguard Worker LOAD(WakeAllConditionVariable);
119*663afb9bSAndroid Build Coastguard Worker LOAD(WakeConditionVariable);
120*663afb9bSAndroid Build Coastguard Worker
121*663afb9bSAndroid Build Coastguard Worker return InitializeConditionVariable_fn && SleepConditionVariableCS_fn &&
122*663afb9bSAndroid Build Coastguard Worker WakeAllConditionVariable_fn && WakeConditionVariable_fn;
123*663afb9bSAndroid Build Coastguard Worker }
124*663afb9bSAndroid Build Coastguard Worker
125*663afb9bSAndroid Build Coastguard Worker /* XXXX Even if we can build this, we don't necessarily want to: the functions
126*663afb9bSAndroid Build Coastguard Worker * in question didn't exist before Vista, so we'd better LoadProc them. */
127*663afb9bSAndroid Build Coastguard Worker static void *
evthread_win32_condvar_alloc(unsigned condflags)128*663afb9bSAndroid Build Coastguard Worker evthread_win32_condvar_alloc(unsigned condflags)
129*663afb9bSAndroid Build Coastguard Worker {
130*663afb9bSAndroid Build Coastguard Worker CONDITION_VARIABLE *cond = mm_malloc(sizeof(CONDITION_VARIABLE));
131*663afb9bSAndroid Build Coastguard Worker if (!cond)
132*663afb9bSAndroid Build Coastguard Worker return NULL;
133*663afb9bSAndroid Build Coastguard Worker InitializeConditionVariable_fn(cond);
134*663afb9bSAndroid Build Coastguard Worker return cond;
135*663afb9bSAndroid Build Coastguard Worker }
136*663afb9bSAndroid Build Coastguard Worker
137*663afb9bSAndroid Build Coastguard Worker static void
evthread_win32_condvar_free(void * cond_)138*663afb9bSAndroid Build Coastguard Worker evthread_win32_condvar_free(void *cond_)
139*663afb9bSAndroid Build Coastguard Worker {
140*663afb9bSAndroid Build Coastguard Worker CONDITION_VARIABLE *cond = cond_;
141*663afb9bSAndroid Build Coastguard Worker /* There doesn't _seem_ to be a cleaup fn here... */
142*663afb9bSAndroid Build Coastguard Worker mm_free(cond);
143*663afb9bSAndroid Build Coastguard Worker }
144*663afb9bSAndroid Build Coastguard Worker
145*663afb9bSAndroid Build Coastguard Worker static int
evthread_win32_condvar_signal(void * cond,int broadcast)146*663afb9bSAndroid Build Coastguard Worker evthread_win32_condvar_signal(void *cond, int broadcast)
147*663afb9bSAndroid Build Coastguard Worker {
148*663afb9bSAndroid Build Coastguard Worker CONDITION_VARIABLE *cond = cond_;
149*663afb9bSAndroid Build Coastguard Worker if (broadcast)
150*663afb9bSAndroid Build Coastguard Worker WakeAllConditionVariable_fn(cond);
151*663afb9bSAndroid Build Coastguard Worker else
152*663afb9bSAndroid Build Coastguard Worker WakeConditionVariable_fn(cond);
153*663afb9bSAndroid Build Coastguard Worker return 0;
154*663afb9bSAndroid Build Coastguard Worker }
155*663afb9bSAndroid Build Coastguard Worker
156*663afb9bSAndroid Build Coastguard Worker static int
evthread_win32_condvar_wait(void * cond_,void * lock_,const struct timeval * tv)157*663afb9bSAndroid Build Coastguard Worker evthread_win32_condvar_wait(void *cond_, void *lock_, const struct timeval *tv)
158*663afb9bSAndroid Build Coastguard Worker {
159*663afb9bSAndroid Build Coastguard Worker CONDITION_VARIABLE *cond = cond_;
160*663afb9bSAndroid Build Coastguard Worker CRITICAL_SECTION *lock = lock_;
161*663afb9bSAndroid Build Coastguard Worker DWORD ms, err;
162*663afb9bSAndroid Build Coastguard Worker BOOL result;
163*663afb9bSAndroid Build Coastguard Worker
164*663afb9bSAndroid Build Coastguard Worker if (tv)
165*663afb9bSAndroid Build Coastguard Worker ms = evutil_tv_to_msec_(tv);
166*663afb9bSAndroid Build Coastguard Worker else
167*663afb9bSAndroid Build Coastguard Worker ms = INFINITE;
168*663afb9bSAndroid Build Coastguard Worker result = SleepConditionVariableCS_fn(cond, lock, ms);
169*663afb9bSAndroid Build Coastguard Worker if (result) {
170*663afb9bSAndroid Build Coastguard Worker if (GetLastError() == WAIT_TIMEOUT)
171*663afb9bSAndroid Build Coastguard Worker return 1;
172*663afb9bSAndroid Build Coastguard Worker else
173*663afb9bSAndroid Build Coastguard Worker return -1;
174*663afb9bSAndroid Build Coastguard Worker } else {
175*663afb9bSAndroid Build Coastguard Worker return 0;
176*663afb9bSAndroid Build Coastguard Worker }
177*663afb9bSAndroid Build Coastguard Worker }
178*663afb9bSAndroid Build Coastguard Worker #endif
179*663afb9bSAndroid Build Coastguard Worker
180*663afb9bSAndroid Build Coastguard Worker struct evthread_win32_cond {
181*663afb9bSAndroid Build Coastguard Worker HANDLE event;
182*663afb9bSAndroid Build Coastguard Worker
183*663afb9bSAndroid Build Coastguard Worker CRITICAL_SECTION lock;
184*663afb9bSAndroid Build Coastguard Worker int n_waiting;
185*663afb9bSAndroid Build Coastguard Worker int n_to_wake;
186*663afb9bSAndroid Build Coastguard Worker int generation;
187*663afb9bSAndroid Build Coastguard Worker };
188*663afb9bSAndroid Build Coastguard Worker
189*663afb9bSAndroid Build Coastguard Worker static void *
evthread_win32_cond_alloc(unsigned flags)190*663afb9bSAndroid Build Coastguard Worker evthread_win32_cond_alloc(unsigned flags)
191*663afb9bSAndroid Build Coastguard Worker {
192*663afb9bSAndroid Build Coastguard Worker struct evthread_win32_cond *cond;
193*663afb9bSAndroid Build Coastguard Worker if (!(cond = mm_malloc(sizeof(struct evthread_win32_cond))))
194*663afb9bSAndroid Build Coastguard Worker return NULL;
195*663afb9bSAndroid Build Coastguard Worker if (InitializeCriticalSectionAndSpinCount(&cond->lock, SPIN_COUNT)==0) {
196*663afb9bSAndroid Build Coastguard Worker mm_free(cond);
197*663afb9bSAndroid Build Coastguard Worker return NULL;
198*663afb9bSAndroid Build Coastguard Worker }
199*663afb9bSAndroid Build Coastguard Worker if ((cond->event = CreateEvent(NULL,TRUE,FALSE,NULL)) == NULL) {
200*663afb9bSAndroid Build Coastguard Worker DeleteCriticalSection(&cond->lock);
201*663afb9bSAndroid Build Coastguard Worker mm_free(cond);
202*663afb9bSAndroid Build Coastguard Worker return NULL;
203*663afb9bSAndroid Build Coastguard Worker }
204*663afb9bSAndroid Build Coastguard Worker cond->n_waiting = cond->n_to_wake = cond->generation = 0;
205*663afb9bSAndroid Build Coastguard Worker return cond;
206*663afb9bSAndroid Build Coastguard Worker }
207*663afb9bSAndroid Build Coastguard Worker
208*663afb9bSAndroid Build Coastguard Worker static void
evthread_win32_cond_free(void * cond_)209*663afb9bSAndroid Build Coastguard Worker evthread_win32_cond_free(void *cond_)
210*663afb9bSAndroid Build Coastguard Worker {
211*663afb9bSAndroid Build Coastguard Worker struct evthread_win32_cond *cond = cond_;
212*663afb9bSAndroid Build Coastguard Worker DeleteCriticalSection(&cond->lock);
213*663afb9bSAndroid Build Coastguard Worker CloseHandle(cond->event);
214*663afb9bSAndroid Build Coastguard Worker mm_free(cond);
215*663afb9bSAndroid Build Coastguard Worker }
216*663afb9bSAndroid Build Coastguard Worker
217*663afb9bSAndroid Build Coastguard Worker static int
evthread_win32_cond_signal(void * cond_,int broadcast)218*663afb9bSAndroid Build Coastguard Worker evthread_win32_cond_signal(void *cond_, int broadcast)
219*663afb9bSAndroid Build Coastguard Worker {
220*663afb9bSAndroid Build Coastguard Worker struct evthread_win32_cond *cond = cond_;
221*663afb9bSAndroid Build Coastguard Worker EnterCriticalSection(&cond->lock);
222*663afb9bSAndroid Build Coastguard Worker if (broadcast)
223*663afb9bSAndroid Build Coastguard Worker cond->n_to_wake = cond->n_waiting;
224*663afb9bSAndroid Build Coastguard Worker else
225*663afb9bSAndroid Build Coastguard Worker ++cond->n_to_wake;
226*663afb9bSAndroid Build Coastguard Worker cond->generation++;
227*663afb9bSAndroid Build Coastguard Worker SetEvent(cond->event);
228*663afb9bSAndroid Build Coastguard Worker LeaveCriticalSection(&cond->lock);
229*663afb9bSAndroid Build Coastguard Worker return 0;
230*663afb9bSAndroid Build Coastguard Worker }
231*663afb9bSAndroid Build Coastguard Worker
232*663afb9bSAndroid Build Coastguard Worker static int
evthread_win32_cond_wait(void * cond_,void * lock_,const struct timeval * tv)233*663afb9bSAndroid Build Coastguard Worker evthread_win32_cond_wait(void *cond_, void *lock_, const struct timeval *tv)
234*663afb9bSAndroid Build Coastguard Worker {
235*663afb9bSAndroid Build Coastguard Worker struct evthread_win32_cond *cond = cond_;
236*663afb9bSAndroid Build Coastguard Worker CRITICAL_SECTION *lock = lock_;
237*663afb9bSAndroid Build Coastguard Worker int generation_at_start;
238*663afb9bSAndroid Build Coastguard Worker int waiting = 1;
239*663afb9bSAndroid Build Coastguard Worker int result = -1;
240*663afb9bSAndroid Build Coastguard Worker DWORD ms = INFINITE, ms_orig = INFINITE, startTime, endTime;
241*663afb9bSAndroid Build Coastguard Worker if (tv)
242*663afb9bSAndroid Build Coastguard Worker ms_orig = ms = evutil_tv_to_msec_(tv);
243*663afb9bSAndroid Build Coastguard Worker
244*663afb9bSAndroid Build Coastguard Worker EnterCriticalSection(&cond->lock);
245*663afb9bSAndroid Build Coastguard Worker ++cond->n_waiting;
246*663afb9bSAndroid Build Coastguard Worker generation_at_start = cond->generation;
247*663afb9bSAndroid Build Coastguard Worker LeaveCriticalSection(&cond->lock);
248*663afb9bSAndroid Build Coastguard Worker
249*663afb9bSAndroid Build Coastguard Worker LeaveCriticalSection(lock);
250*663afb9bSAndroid Build Coastguard Worker
251*663afb9bSAndroid Build Coastguard Worker startTime = GetTickCount();
252*663afb9bSAndroid Build Coastguard Worker do {
253*663afb9bSAndroid Build Coastguard Worker DWORD res;
254*663afb9bSAndroid Build Coastguard Worker res = WaitForSingleObject(cond->event, ms);
255*663afb9bSAndroid Build Coastguard Worker EnterCriticalSection(&cond->lock);
256*663afb9bSAndroid Build Coastguard Worker if (cond->n_to_wake &&
257*663afb9bSAndroid Build Coastguard Worker cond->generation != generation_at_start) {
258*663afb9bSAndroid Build Coastguard Worker --cond->n_to_wake;
259*663afb9bSAndroid Build Coastguard Worker --cond->n_waiting;
260*663afb9bSAndroid Build Coastguard Worker result = 0;
261*663afb9bSAndroid Build Coastguard Worker waiting = 0;
262*663afb9bSAndroid Build Coastguard Worker goto out;
263*663afb9bSAndroid Build Coastguard Worker } else if (res != WAIT_OBJECT_0) {
264*663afb9bSAndroid Build Coastguard Worker result = (res==WAIT_TIMEOUT) ? 1 : -1;
265*663afb9bSAndroid Build Coastguard Worker --cond->n_waiting;
266*663afb9bSAndroid Build Coastguard Worker waiting = 0;
267*663afb9bSAndroid Build Coastguard Worker goto out;
268*663afb9bSAndroid Build Coastguard Worker } else if (ms != INFINITE) {
269*663afb9bSAndroid Build Coastguard Worker endTime = GetTickCount();
270*663afb9bSAndroid Build Coastguard Worker if (startTime + ms_orig <= endTime) {
271*663afb9bSAndroid Build Coastguard Worker result = 1; /* Timeout */
272*663afb9bSAndroid Build Coastguard Worker --cond->n_waiting;
273*663afb9bSAndroid Build Coastguard Worker waiting = 0;
274*663afb9bSAndroid Build Coastguard Worker goto out;
275*663afb9bSAndroid Build Coastguard Worker } else {
276*663afb9bSAndroid Build Coastguard Worker ms = startTime + ms_orig - endTime;
277*663afb9bSAndroid Build Coastguard Worker }
278*663afb9bSAndroid Build Coastguard Worker }
279*663afb9bSAndroid Build Coastguard Worker /* If we make it here, we are still waiting. */
280*663afb9bSAndroid Build Coastguard Worker if (cond->n_to_wake == 0) {
281*663afb9bSAndroid Build Coastguard Worker /* There is nobody else who should wake up; reset
282*663afb9bSAndroid Build Coastguard Worker * the event. */
283*663afb9bSAndroid Build Coastguard Worker ResetEvent(cond->event);
284*663afb9bSAndroid Build Coastguard Worker }
285*663afb9bSAndroid Build Coastguard Worker out:
286*663afb9bSAndroid Build Coastguard Worker LeaveCriticalSection(&cond->lock);
287*663afb9bSAndroid Build Coastguard Worker } while (waiting);
288*663afb9bSAndroid Build Coastguard Worker
289*663afb9bSAndroid Build Coastguard Worker EnterCriticalSection(lock);
290*663afb9bSAndroid Build Coastguard Worker
291*663afb9bSAndroid Build Coastguard Worker EnterCriticalSection(&cond->lock);
292*663afb9bSAndroid Build Coastguard Worker if (!cond->n_waiting)
293*663afb9bSAndroid Build Coastguard Worker ResetEvent(cond->event);
294*663afb9bSAndroid Build Coastguard Worker LeaveCriticalSection(&cond->lock);
295*663afb9bSAndroid Build Coastguard Worker
296*663afb9bSAndroid Build Coastguard Worker return result;
297*663afb9bSAndroid Build Coastguard Worker }
298*663afb9bSAndroid Build Coastguard Worker
299*663afb9bSAndroid Build Coastguard Worker int
evthread_use_windows_threads(void)300*663afb9bSAndroid Build Coastguard Worker evthread_use_windows_threads(void)
301*663afb9bSAndroid Build Coastguard Worker {
302*663afb9bSAndroid Build Coastguard Worker struct evthread_lock_callbacks cbs = {
303*663afb9bSAndroid Build Coastguard Worker EVTHREAD_LOCK_API_VERSION,
304*663afb9bSAndroid Build Coastguard Worker EVTHREAD_LOCKTYPE_RECURSIVE,
305*663afb9bSAndroid Build Coastguard Worker evthread_win32_lock_create,
306*663afb9bSAndroid Build Coastguard Worker evthread_win32_lock_free,
307*663afb9bSAndroid Build Coastguard Worker evthread_win32_lock,
308*663afb9bSAndroid Build Coastguard Worker evthread_win32_unlock
309*663afb9bSAndroid Build Coastguard Worker };
310*663afb9bSAndroid Build Coastguard Worker
311*663afb9bSAndroid Build Coastguard Worker
312*663afb9bSAndroid Build Coastguard Worker struct evthread_condition_callbacks cond_cbs = {
313*663afb9bSAndroid Build Coastguard Worker EVTHREAD_CONDITION_API_VERSION,
314*663afb9bSAndroid Build Coastguard Worker evthread_win32_cond_alloc,
315*663afb9bSAndroid Build Coastguard Worker evthread_win32_cond_free,
316*663afb9bSAndroid Build Coastguard Worker evthread_win32_cond_signal,
317*663afb9bSAndroid Build Coastguard Worker evthread_win32_cond_wait
318*663afb9bSAndroid Build Coastguard Worker };
319*663afb9bSAndroid Build Coastguard Worker #ifdef WIN32_HAVE_CONDITION_VARIABLES
320*663afb9bSAndroid Build Coastguard Worker struct evthread_condition_callbacks condvar_cbs = {
321*663afb9bSAndroid Build Coastguard Worker EVTHREAD_CONDITION_API_VERSION,
322*663afb9bSAndroid Build Coastguard Worker evthread_win32_condvar_alloc,
323*663afb9bSAndroid Build Coastguard Worker evthread_win32_condvar_free,
324*663afb9bSAndroid Build Coastguard Worker evthread_win32_condvar_signal,
325*663afb9bSAndroid Build Coastguard Worker evthread_win32_condvar_wait
326*663afb9bSAndroid Build Coastguard Worker };
327*663afb9bSAndroid Build Coastguard Worker #endif
328*663afb9bSAndroid Build Coastguard Worker
329*663afb9bSAndroid Build Coastguard Worker evthread_set_lock_callbacks(&cbs);
330*663afb9bSAndroid Build Coastguard Worker evthread_set_id_callback(evthread_win32_get_id);
331*663afb9bSAndroid Build Coastguard Worker #ifdef WIN32_HAVE_CONDITION_VARIABLES
332*663afb9bSAndroid Build Coastguard Worker if (evthread_win32_condvar_init()) {
333*663afb9bSAndroid Build Coastguard Worker evthread_set_condition_callbacks(&condvar_cbs);
334*663afb9bSAndroid Build Coastguard Worker return 0;
335*663afb9bSAndroid Build Coastguard Worker }
336*663afb9bSAndroid Build Coastguard Worker #endif
337*663afb9bSAndroid Build Coastguard Worker evthread_set_condition_callbacks(&cond_cbs);
338*663afb9bSAndroid Build Coastguard Worker
339*663afb9bSAndroid Build Coastguard Worker return 0;
340*663afb9bSAndroid Build Coastguard Worker }
341*663afb9bSAndroid Build Coastguard Worker
342