~siretart/vlc/debian-packaging

« back to all changes in this revision

Viewing changes to src/os2/thread.c

  • Committer: Sebastian Ramacher
  • Date: 2016-01-31 20:58:37 UTC
  • mfrom: (1.2.39)
  • Revision ID: git-v1:b7ac1de93ecf7cd3d86898544433974ce0af7086
Merge tag 'upstream/2.2.2'

Upstream version 2.2.2

# gpg: Signature made Sun 31 Jan 2016 21:57:53 CET using RSA key ID 6EA71993
# gpg: Good signature from "Sebastian Ramacher <sebastian@ramacher.at>"
# gpg:                 aka "Sebastian Ramacher <s.ramacher@gmail.com>"
# gpg:                 aka "Sebastian Ramacher <s.ramacher@gmx.at>"
# gpg:                 aka "Sebastian Ramacher <s.ramacher@student.tugraz.at>"
# gpg:                 aka "Sebastian Ramacher <sramacher@debian.org>"
# gpg:                 aka "Sebastian Ramacher <sebastian.ramacher@iaik.tugraz.at>"

Show diffs side-by-side

added added

removed removed

Lines of Context:
45
45
#include <sys/time.h>
46
46
#include <sys/select.h>
47
47
 
 
48
#include <sys/builtin.h>
 
49
 
48
50
static vlc_threadvar_t thread_key;
49
51
 
50
52
/**
68
70
 
69
71
static void vlc_cancel_self (PVOID dummy);
70
72
 
71
 
static ULONG vlc_DosWaitEventSemEx( HEV hev, ULONG ulTimeout, BOOL fCancelable )
 
73
static ULONG vlc_DosWaitEventSemEx( HEV hev, ULONG ulTimeout )
72
74
{
73
75
    HMUX      hmux;
74
76
    SEMRECORD asr[ 2 ];
77
79
    ULONG     rc;
78
80
 
79
81
    struct vlc_thread *th = vlc_threadvar_get( thread_key );
80
 
    if( th == NULL || !fCancelable )
 
82
    if( th == NULL || !th->killable )
81
83
    {
82
84
        /* Main thread - cannot be cancelled anyway
83
85
         * Alien thread - out of our control
 
86
         * Cancel disabled thread - ignore cancel
84
87
         */
85
88
        if( hev != NULLHANDLE )
86
89
            return DosWaitEventSem( hev, ulTimeout );
116
119
 
117
120
static ULONG vlc_WaitForSingleObject (HEV hev, ULONG ulTimeout)
118
121
{
119
 
    return vlc_DosWaitEventSemEx( hev, ulTimeout, TRUE );
 
122
    return vlc_DosWaitEventSemEx( hev, ulTimeout );
120
123
}
121
124
 
122
125
static ULONG vlc_Sleep (ULONG ulTimeout)
123
126
{
124
 
    ULONG rc = vlc_DosWaitEventSemEx( NULLHANDLE, ulTimeout, TRUE );
 
127
    ULONG rc = vlc_DosWaitEventSemEx( NULLHANDLE, ulTimeout );
125
128
 
126
129
    return ( rc != ERROR_TIMEOUT ) ? rc : 0;
127
130
}
261
264
 
262
265
static void vlc_cond_init_common (vlc_cond_t *p_condvar, unsigned clock)
263
266
{
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))
266
269
        abort();
 
270
 
 
271
    p_condvar->waiters = 0;
 
272
    p_condvar->signaled = 0;
267
273
    p_condvar->clock = clock;
268
274
}
269
275
 
280
286
void vlc_cond_destroy (vlc_cond_t *p_condvar)
281
287
{
282
288
    DosCloseEventSem( p_condvar->hev );
 
289
    DosCloseEventSem( p_condvar->hevAck );
283
290
}
284
291
 
285
292
void vlc_cond_signal (vlc_cond_t *p_condvar)
287
294
    if (!p_condvar->hev)
288
295
        return;
289
296
 
290
 
    /* This is suboptimal but works. */
291
 
    vlc_cond_broadcast (p_condvar);
 
297
    if (!__atomic_cmpxchg32 (&p_condvar->waiters, 0, 0))
 
298
    {
 
299
        ULONG ulPost;
 
300
 
 
301
        __atomic_xchg (&p_condvar->signaled, 1);
 
302
        DosPostEventSem (p_condvar->hev);
 
303
 
 
304
        DosWaitEventSem (p_condvar->hevAck, SEM_INDEFINITE_WAIT);
 
305
        DosResetEventSem (p_condvar->hevAck, &ulPost);
 
306
    }
292
307
}
293
308
 
294
309
void vlc_cond_broadcast (vlc_cond_t *p_condvar)
296
311
    if (!p_condvar->hev)
297
312
        return;
298
313
 
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);
 
316
}
 
317
 
 
318
static int vlc_cond_wait_common (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
 
319
                                 ULONG ulTimeout)
 
320
{
 
321
    ULONG ulPost;
 
322
    ULONG rc;
 
323
 
 
324
    do
 
325
    {
 
326
        vlc_testcancel();
 
327
 
 
328
        __atomic_increment (&p_condvar->waiters);
 
329
 
 
330
        vlc_mutex_unlock (p_mutex);
 
331
 
 
332
        do
 
333
        {
 
334
            rc = vlc_WaitForSingleObject( p_condvar->hev, ulTimeout );
 
335
            if (rc == NO_ERROR)
 
336
                DosResetEventSem (p_condvar->hev, &ulPost);
 
337
        } while (rc == NO_ERROR &&
 
338
                 __atomic_cmpxchg32 (&p_condvar->signaled, 0, 1) == 0);
 
339
 
 
340
        __atomic_decrement (&p_condvar->waiters);
 
341
 
 
342
        DosPostEventSem (p_condvar->hevAck);
 
343
 
 
344
        vlc_mutex_lock (p_mutex);
 
345
    } while( rc == ERROR_INTERRUPT );
 
346
 
 
347
    return rc ? ETIMEDOUT : 0;
301
348
}
302
349
 
303
350
void vlc_cond_wait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex)
304
351
{
305
 
    ULONG ulPost;
306
 
    ULONG rc;
307
 
 
308
352
    if (!p_condvar->hev)
309
353
    {   /* FIXME FIXME FIXME */
310
354
        msleep (50000);
311
355
        return;
312
356
    }
313
357
 
314
 
    do
315
 
    {
316
 
        vlc_testcancel();
317
 
 
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 );
322
 
 
323
 
    DosResetEventSem( p_condvar->hev, &ulPost );
 
358
    vlc_cond_wait_common (p_condvar, p_mutex, SEM_INDEFINITE_WAIT);
324
359
}
325
360
 
326
361
int vlc_cond_timedwait (vlc_cond_t *p_condvar, vlc_mutex_t *p_mutex,
327
362
                        mtime_t deadline)
328
363
{
329
364
    ULONG   ulTimeout;
330
 
    ULONG   ulPost;
331
 
    ULONG   rc;
332
365
 
333
366
    if (!p_condvar->hev)
334
367
    {   /* FIXME FIXME FIXME */
336
369
        return 0;
337
370
    }
338
371
 
339
 
    do
 
372
    mtime_t total;
 
373
    switch (p_condvar->clock)
340
374
    {
341
 
        vlc_testcancel();
342
 
 
343
 
        mtime_t total;
344
 
        switch (p_condvar->clock)
 
375
        case CLOCK_REALTIME:
345
376
        {
346
 
            case CLOCK_REALTIME: /* FIXME? sub-second precision */
347
 
                total = CLOCK_FREQ * time (NULL);
348
 
                break;
349
 
            default:
350
 
                assert (p_condvar->clock == CLOCK_MONOTONIC);
351
 
                total = mdate();
352
 
                break;
 
377
            struct timeval tv;
 
378
            gettimeofday (&tv, NULL);
 
379
 
 
380
            total = CLOCK_FREQ * tv.tv_sec +
 
381
                    CLOCK_FREQ * tv.tv_usec / 1000000L;
 
382
            break;
353
383
        }
354
 
        total = (deadline - total) / 1000;
355
 
        if( total < 0 )
356
 
            total = 0;
357
 
 
358
 
        ulTimeout = ( total > 0x7fffffff ) ? 0x7fffffff : total;
359
 
 
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 );
364
 
 
365
 
    DosResetEventSem( p_condvar->hev, &ulPost );
366
 
 
367
 
    return rc ? ETIMEDOUT : 0;
 
384
        default:
 
385
            assert (p_condvar->clock == CLOCK_MONOTONIC);
 
386
            total = mdate();
 
387
            break;
 
388
    }
 
389
    total = (deadline - total) / 1000;
 
390
    if( total < 0 )
 
391
        total = 0;
 
392
 
 
393
    ulTimeout = ( total > 0x7fffffff ) ? 0x7fffffff : total;
 
394
 
 
395
    return vlc_cond_wait_common (p_condvar, p_mutex, ulTimeout);
368
396
}
369
397
 
370
398
/*** Thread-specific variables (TLS) ***/