69
71
static void vlc_cancel_self (PVOID dummy);
71
static ULONG vlc_DosWaitEventSemEx( HEV hev, ULONG ulTimeout, BOOL fCancelable )
73
static ULONG vlc_DosWaitEventSemEx( HEV hev, ULONG ulTimeout )
74
76
SEMRECORD asr[ 2 ];
79
81
struct vlc_thread *th = vlc_threadvar_get( thread_key );
80
if( th == NULL || !fCancelable )
82
if( th == NULL || !th->killable )
82
84
/* Main thread - cannot be cancelled anyway
83
85
* Alien thread - out of our control
86
* Cancel disabled thread - ignore cancel
85
88
if( hev != NULLHANDLE )
86
89
return DosWaitEventSem( hev, ulTimeout );
117
120
static ULONG vlc_WaitForSingleObject (HEV hev, ULONG ulTimeout)
119
return vlc_DosWaitEventSemEx( hev, ulTimeout, TRUE );
122
return vlc_DosWaitEventSemEx( hev, ulTimeout );
122
125
static ULONG vlc_Sleep (ULONG ulTimeout)
124
ULONG rc = vlc_DosWaitEventSemEx( NULLHANDLE, ulTimeout, TRUE );
127
ULONG rc = vlc_DosWaitEventSemEx( NULLHANDLE, ulTimeout );
126
129
return ( rc != ERROR_TIMEOUT ) ? rc : 0;
262
265
static void vlc_cond_init_common (vlc_cond_t *p_condvar, unsigned clock)
264
/* Create a manual-reset event (manual reset is needed for broadcast). */
265
if (DosCreateEventSem (NULL, &p_condvar->hev, 0, FALSE))
267
if (DosCreateEventSem (NULL, &p_condvar->hev, 0, FALSE) ||
268
DosCreateEventSem (NULL, &p_condvar->hevAck, 0, FALSE))
271
p_condvar->waiters = 0;
272
p_condvar->signaled = 0;
267
273
p_condvar->clock = clock;
287
294
if (!p_condvar->hev)
290
/* This is suboptimal but works. */
291
vlc_cond_broadcast (p_condvar);
297
if (!__atomic_cmpxchg32 (&p_condvar->waiters, 0, 0))
301
__atomic_xchg (&p_condvar->signaled, 1);
302
DosPostEventSem (p_condvar->hev);
304
DosWaitEventSem (p_condvar->hevAck, SEM_INDEFINITE_WAIT);
305
DosResetEventSem (p_condvar->hevAck, &ulPost);
294
309
void vlc_cond_broadcast (vlc_cond_t *p_condvar)
296
311
if (!p_condvar->hev)
299
/* Wake all threads up (as the event HANDLE has manual reset) */
300
DosPostEventSem( p_condvar->hev );
314
while (!__atomic_cmpxchg32 (&p_condvar->waiters, 0, 0))
315
vlc_cond_signal (p_condvar);
318
static int vlc_cond_wait_common (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
328
__atomic_increment (&p_condvar->waiters);
330
vlc_mutex_unlock (p_mutex);
334
rc = vlc_WaitForSingleObject( p_condvar->hev, ulTimeout );
336
DosResetEventSem (p_condvar->hev, &ulPost);
337
} while (rc == NO_ERROR &&
338
__atomic_cmpxchg32 (&p_condvar->signaled, 0, 1) == 0);
340
__atomic_decrement (&p_condvar->waiters);
342
DosPostEventSem (p_condvar->hevAck);
344
vlc_mutex_lock (p_mutex);
345
} while( rc == ERROR_INTERRUPT );
347
return rc ? ETIMEDOUT : 0;
303
350
void vlc_cond_wait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex)
308
352
if (!p_condvar->hev)
309
353
{ /* FIXME FIXME FIXME */
318
vlc_mutex_unlock (p_mutex);
319
rc = vlc_WaitForSingleObject( p_condvar->hev, SEM_INDEFINITE_WAIT );
320
vlc_mutex_lock (p_mutex);
321
} while( rc == ERROR_INTERRUPT );
323
DosResetEventSem( p_condvar->hev, &ulPost );
358
vlc_cond_wait_common (p_condvar, p_mutex, SEM_INDEFINITE_WAIT);
326
361
int vlc_cond_timedwait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
327
362
mtime_t deadline)
333
366
if (!p_condvar->hev)
334
367
{ /* FIXME FIXME FIXME */
373
switch (p_condvar->clock)
344
switch (p_condvar->clock)
346
case CLOCK_REALTIME: /* FIXME? sub-second precision */
347
total = CLOCK_FREQ * time (NULL);
350
assert (p_condvar->clock == CLOCK_MONOTONIC);
378
gettimeofday (&tv, NULL);
380
total = CLOCK_FREQ * tv.tv_sec +
381
CLOCK_FREQ * tv.tv_usec / 1000000L;
354
total = (deadline - total) / 1000;
358
ulTimeout = ( total > 0x7fffffff ) ? 0x7fffffff : total;
360
vlc_mutex_unlock (p_mutex);
361
rc = vlc_WaitForSingleObject( p_condvar->hev, ulTimeout );
362
vlc_mutex_lock (p_mutex);
363
} while( rc == ERROR_INTERRUPT );
365
DosResetEventSem( p_condvar->hev, &ulPost );
367
return rc ? ETIMEDOUT : 0;
385
assert (p_condvar->clock == CLOCK_MONOTONIC);
389
total = (deadline - total) / 1000;
393
ulTimeout = ( total > 0x7fffffff ) ? 0x7fffffff : total;
395
return vlc_cond_wait_common (p_condvar, p_mutex, ulTimeout);
370
398
/*** Thread-specific variables (TLS) ***/