src/thread/pthread/SDL_syssem.c
changeset 5106 d547877e355e
parent 3697 f7b03b6838cb
child 5262 b530ef003506
equal deleted inserted replaced
5104:5fe0330b0fd6 5106:d547877e355e
    19     Sam Lantinga
    19     Sam Lantinga
    20     slouken@libsdl.org
    20     slouken@libsdl.org
    21 */
    21 */
    22 #include "SDL_config.h"
    22 #include "SDL_config.h"
    23 
    23 
       
    24 #include <errno.h>
    24 #include <pthread.h>
    25 #include <pthread.h>
    25 #include <semaphore.h>
    26 #include <semaphore.h>
    26 
    27 
    27 #include "SDL_thread.h"
    28 #include "SDL_thread.h"
    28 #include "SDL_timer.h"
    29 #include "SDL_timer.h"
   100 
   101 
   101 int
   102 int
   102 SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
   103 SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
   103 {
   104 {
   104     int retval;
   105     int retval;
       
   106     struct timeval now;
       
   107     struct timespec ts_timeout;
   105 
   108 
   106     if (!sem) {
   109     if (!sem) {
   107         SDL_SetError("Passed a NULL semaphore");
   110         SDL_SetError("Passed a NULL semaphore");
   108         return -1;
   111         return -1;
   109     }
   112     }
   114     }
   117     }
   115     if (timeout == SDL_MUTEX_MAXWAIT) {
   118     if (timeout == SDL_MUTEX_MAXWAIT) {
   116         return SDL_SemWait(sem);
   119         return SDL_SemWait(sem);
   117     }
   120     }
   118 
   121 
   119     /* Ack!  We have to busy wait... */
   122     /* Setup the timeout. sem_timedwait doesn't wait for
   120     /* FIXME: Use sem_timedwait()? */
   123     * a lapse of time, but until we reach a certain time.
   121     timeout += SDL_GetTicks();
   124     * This time is now plus the timeout.
       
   125     */
       
   126     gettimeofday(&now, NULL);
       
   127 
       
   128     /* Add our timeout to current time */
       
   129     now.tv_usec += (timeout % 1000) * 1000;
       
   130     now.tv_sec += timeout / 1000;
       
   131 
       
   132     /* Wrap the second if needed */
       
   133     if ( now.tv_usec >= 1000000 ) {
       
   134         now.tv_usec -= 1000000;
       
   135         now.tv_sec ++;
       
   136     }
       
   137 
       
   138     /* Convert to timespec */
       
   139     ts_timeout.tv_sec = now.tv_sec;
       
   140     ts_timeout.tv_nsec = now.tv_usec * 1000;
       
   141 
       
   142     /* Wait. */
   122     do {
   143     do {
   123         retval = SDL_SemTryWait(sem);
   144         retval = sem_timedwait(&sem->sem, &ts_timeout);
   124         if (retval == 0) {
   145     } while (retval < 0 && errno == EINTR);
   125             break;
   146 
   126         }
   147     if (retval < 0) {
   127         SDL_Delay(1);
   148         SDL_SetError("sem_timedwait() failed");
   128     } while (SDL_GetTicks() < timeout);
   149     }
   129 
   150 
   130     return retval;
   151     return retval;
   131 }
   152 }
   132 
   153 
   133 Uint32
   154 Uint32