22 #include "mysys_priv.h"
25 #include <sys/timeb.h>
34 typedef VOID (WINAPI * InitializeConditionVariableProc)
35 (PCONDITION_VARIABLE ConditionVariable);
37 typedef BOOL (WINAPI * SleepConditionVariableCSProc)
38 (PCONDITION_VARIABLE ConditionVariable,
39 PCRITICAL_SECTION CriticalSection,
40 DWORD dwMilliseconds);
42 typedef VOID (WINAPI * WakeAllConditionVariableProc)
43 (PCONDITION_VARIABLE ConditionVariable);
45 typedef VOID (WINAPI * WakeConditionVariableProc)
46 (PCONDITION_VARIABLE ConditionVariable);
48 static InitializeConditionVariableProc my_InitializeConditionVariable;
49 static SleepConditionVariableCSProc my_SleepConditionVariableCS;
50 static WakeAllConditionVariableProc my_WakeAllConditionVariable;
51 static WakeConditionVariableProc my_WakeConditionVariable;
59 static BOOL have_native_conditions= FALSE;
66 static void check_native_cond_availability(
void)
68 HMODULE module= GetModuleHandle(
"kernel32");
70 my_InitializeConditionVariable= (InitializeConditionVariableProc)
71 GetProcAddress(module,
"InitializeConditionVariable");
72 my_SleepConditionVariableCS= (SleepConditionVariableCSProc)
73 GetProcAddress(module,
"SleepConditionVariableCS");
74 my_WakeAllConditionVariable= (WakeAllConditionVariableProc)
75 GetProcAddress(module,
"WakeAllConditionVariable");
76 my_WakeConditionVariable= (WakeConditionVariableProc)
77 GetProcAddress(module,
"WakeConditionVariable");
79 if (my_InitializeConditionVariable)
80 have_native_conditions= TRUE;
89 static DWORD get_milliseconds(
const struct timespec *abstime)
97 GetSystemTimeAsFileTime(&now.ft);
104 millis= (abstime->tv.i64 - now.i64) / 10000;
114 if (millis > abstime->max_timeout_msec)
115 millis= abstime->max_timeout_msec;
117 if (millis > UINT_MAX)
120 return (DWORD)millis;
128 static int legacy_cond_init(pthread_cond_t *cond,
const pthread_condattr_t *attr)
131 InitializeCriticalSection(&cond->lock_waiting);
133 cond->events[SIGNAL]= CreateEvent(NULL,
139 cond->events[BROADCAST]= CreateEvent(NULL,
145 cond->broadcast_block_event= CreateEvent(NULL,
150 if( cond->events[SIGNAL] == NULL ||
151 cond->events[BROADCAST] == NULL ||
152 cond->broadcast_block_event == NULL )
158 static int legacy_cond_destroy(pthread_cond_t *cond)
160 DeleteCriticalSection(&cond->lock_waiting);
162 if (CloseHandle(cond->events[SIGNAL]) == 0 ||
163 CloseHandle(cond->events[BROADCAST]) == 0 ||
164 CloseHandle(cond->broadcast_block_event) == 0)
170 static int legacy_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
176 timeout= get_milliseconds(abstime);
182 WaitForSingleObject(cond->broadcast_block_event, INFINITE);
184 EnterCriticalSection(&cond->lock_waiting);
186 LeaveCriticalSection(&cond->lock_waiting);
188 LeaveCriticalSection(mutex);
189 result= WaitForMultipleObjects(2, cond->events, FALSE, timeout);
191 EnterCriticalSection(&cond->lock_waiting);
194 if (cond->waiting == 0)
201 ResetEvent(cond->events[BROADCAST]);
203 SetEvent(cond->broadcast_block_event);
205 LeaveCriticalSection(&cond->lock_waiting);
207 EnterCriticalSection(mutex);
209 return result == WAIT_TIMEOUT ? ETIMEDOUT : 0;
212 static int legacy_cond_signal(pthread_cond_t *cond)
214 EnterCriticalSection(&cond->lock_waiting);
216 if(cond->waiting > 0)
217 SetEvent(cond->events[SIGNAL]);
219 LeaveCriticalSection(&cond->lock_waiting);
225 static int legacy_cond_broadcast(pthread_cond_t *cond)
227 EnterCriticalSection(&cond->lock_waiting);
233 if(cond->waiting > 0)
236 ResetEvent(cond->broadcast_block_event);
238 SetEvent(cond->events[BROADCAST]);
241 LeaveCriticalSection(&cond->lock_waiting);
251 int pthread_cond_init(pthread_cond_t *cond,
const pthread_condattr_t *attr)
261 static my_pthread_once_t once_control= MY_PTHREAD_ONCE_INIT;
262 my_pthread_once(&once_control, check_native_cond_availability);
264 if (have_native_conditions)
266 my_InitializeConditionVariable(&cond->native_cond);
270 return legacy_cond_init(cond, attr);
274 int pthread_cond_destroy(pthread_cond_t *cond)
276 if (have_native_conditions)
279 return legacy_cond_destroy(cond);
283 int pthread_cond_broadcast(pthread_cond_t *cond)
285 if (have_native_conditions)
287 my_WakeAllConditionVariable(&cond->native_cond);
291 return legacy_cond_broadcast(cond);
295 int pthread_cond_signal(pthread_cond_t *cond)
297 if (have_native_conditions)
299 my_WakeConditionVariable(&cond->native_cond);
303 return legacy_cond_signal(cond);
307 int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
310 if (have_native_conditions)
312 DWORD timeout= get_milliseconds(abstime);
313 if (!my_SleepConditionVariableCS(&cond->native_cond, mutex, timeout))
318 return legacy_cond_timedwait(cond, mutex, abstime);
322 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
324 return pthread_cond_timedwait(cond, mutex, NULL);
328 int pthread_attr_init(pthread_attr_t *connect_att)
330 connect_att->dwStackSize = 0;
331 connect_att->dwCreatingFlag = 0;
335 int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack)
337 connect_att->dwStackSize=stack;
341 int pthread_attr_destroy(pthread_attr_t *connect_att)
343 memset(connect_att, 0,
sizeof(*connect_att));
351 struct tm *localtime_r(
const time_t *timep,
struct tm *tmp)
353 if (*timep == (time_t) -1)
355 memset(tmp, 0,
sizeof(*tmp));
359 struct tm *res=localtime(timep);
362 memset(tmp, 0,
sizeof(*tmp));