src/thread/pthread/SDL_syssem.c
changeset 5106 d547877e355e
parent 3697 f7b03b6838cb
child 5262 b530ef003506
     1.1 --- a/src/thread/pthread/SDL_syssem.c	Thu Jan 27 00:19:46 2011 -0800
     1.2 +++ b/src/thread/pthread/SDL_syssem.c	Thu Jan 27 00:34:12 2011 -0800
     1.3 @@ -21,6 +21,7 @@
     1.4  */
     1.5  #include "SDL_config.h"
     1.6  
     1.7 +#include <errno.h>
     1.8  #include <pthread.h>
     1.9  #include <semaphore.h>
    1.10  
    1.11 @@ -102,6 +103,8 @@
    1.12  SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
    1.13  {
    1.14      int retval;
    1.15 +    struct timeval now;
    1.16 +    struct timespec ts_timeout;
    1.17  
    1.18      if (!sem) {
    1.19          SDL_SetError("Passed a NULL semaphore");
    1.20 @@ -116,16 +119,34 @@
    1.21          return SDL_SemWait(sem);
    1.22      }
    1.23  
    1.24 -    /* Ack!  We have to busy wait... */
    1.25 -    /* FIXME: Use sem_timedwait()? */
    1.26 -    timeout += SDL_GetTicks();
    1.27 +    /* Setup the timeout. sem_timedwait doesn't wait for
    1.28 +    * a lapse of time, but until we reach a certain time.
    1.29 +    * This time is now plus the timeout.
    1.30 +    */
    1.31 +    gettimeofday(&now, NULL);
    1.32 +
    1.33 +    /* Add our timeout to current time */
    1.34 +    now.tv_usec += (timeout % 1000) * 1000;
    1.35 +    now.tv_sec += timeout / 1000;
    1.36 +
    1.37 +    /* Wrap the second if needed */
    1.38 +    if ( now.tv_usec >= 1000000 ) {
    1.39 +        now.tv_usec -= 1000000;
    1.40 +        now.tv_sec ++;
    1.41 +    }
    1.42 +
    1.43 +    /* Convert to timespec */
    1.44 +    ts_timeout.tv_sec = now.tv_sec;
    1.45 +    ts_timeout.tv_nsec = now.tv_usec * 1000;
    1.46 +
    1.47 +    /* Wait. */
    1.48      do {
    1.49 -        retval = SDL_SemTryWait(sem);
    1.50 -        if (retval == 0) {
    1.51 -            break;
    1.52 -        }
    1.53 -        SDL_Delay(1);
    1.54 -    } while (SDL_GetTicks() < timeout);
    1.55 +        retval = sem_timedwait(&sem->sem, &ts_timeout);
    1.56 +    } while (retval < 0 && errno == EINTR);
    1.57 +
    1.58 +    if (retval < 0) {
    1.59 +        SDL_SetError("sem_timedwait() failed");
    1.60 +    }
    1.61  
    1.62      return retval;
    1.63  }