SDL_syscond.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:5k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.     SDL - Simple DirectMedia Layer
  3.     Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002  Sam Lantinga
  4.     This library is free software; you can redistribute it and/or
  5.     modify it under the terms of the GNU Library General Public
  6.     License as published by the Free Software Foundation; either
  7.     version 2 of the License, or (at your option) any later version.
  8.     This library is distributed in the hope that it will be useful,
  9.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  11.     Library General Public License for more details.
  12.     You should have received a copy of the GNU Library General Public
  13.     License along with this library; if not, write to the Free
  14.     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  15.     Sam Lantinga
  16.     slouken@libsdl.org
  17. */
  18. #ifdef SAVE_RCSID
  19. static char rcsid =
  20.  "@(#) $Id: SDL_syscond.c,v 1.4 2002/04/22 21:38:03 wmay Exp $";
  21. #endif
  22. #ifdef linux
  23. /* Look to see if glibc is available, and if so, what version */
  24. #include <features.h>
  25. #if (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0)
  26. #warning Working around a bug in glibc 2.0 pthreads
  27. #undef SDL_USE_PTHREADS
  28. /* The bug is actually a problem where threads are suspended, but don't
  29.    wake up when the thread manager sends them a signal.  This is a problem
  30.    with thread creation too, but it happens less often. :-/
  31.    We avoid this by using System V IPC for mutexes.
  32.  */
  33. #endif /* glibc 2.0 */
  34. #endif /* linux */
  35. #ifdef SDL_USE_PTHREADS
  36. #include <sys/time.h>
  37. #include <unistd.h>
  38. #include <errno.h>
  39. #include <stdlib.h>
  40. #include <pthread.h>
  41. #include "SDL_error.h"
  42. #include "SDL_thread.h"
  43. #include "SDL_sysmutex_c.h"
  44. #if defined(PTHREAD_NO_RECURSIVE_MUTEX) && !defined(__bsdi__)
  45. #error You need to use the generic condition variable implementation
  46. #endif
  47. struct SDL_cond
  48. {
  49. pthread_cond_t cond;
  50. };
  51. /* Create a condition variable */
  52. SDL_cond * SDL_CreateCond(void)
  53. {
  54. SDL_cond *cond;
  55. cond = (SDL_cond *) malloc(sizeof(SDL_cond));
  56. if ( cond ) {
  57. if ( pthread_cond_init(&cond->cond, NULL) < 0 ) {
  58. SDL_SetError("pthread_cond_init() failed");
  59. free(cond);
  60. cond = NULL;
  61. }
  62. }
  63. return(cond);
  64. }
  65. /* Destroy a condition variable */
  66. void SDL_DestroyCond(SDL_cond *cond)
  67. {
  68. if ( cond ) {
  69. pthread_cond_destroy(&cond->cond);
  70. free(cond);
  71. }
  72. }
  73. /* Restart one of the threads that are waiting on the condition variable */
  74. int SDL_CondSignal(SDL_cond *cond)
  75. {
  76. int retval;
  77. if ( ! cond ) {
  78. SDL_SetError("Passed a NULL condition variable");
  79. return -1;
  80. }
  81. retval = 0;
  82. if ( pthread_cond_signal(&cond->cond) != 0 ) {
  83. SDL_SetError("pthread_cond_signal() failed");
  84. retval = -1;
  85. }
  86. return retval;
  87. }
  88. /* Restart all threads that are waiting on the condition variable */
  89. int SDL_CondBroadcast(SDL_cond *cond)
  90. {
  91. int retval;
  92. if ( ! cond ) {
  93. SDL_SetError("Passed a NULL condition variable");
  94. return -1;
  95. }
  96. retval = 0;
  97. if ( pthread_cond_broadcast(&cond->cond) != 0 ) {
  98. SDL_SetError("pthread_cond_broadcast() failed");
  99. retval = -1;
  100. }
  101. return retval;
  102. }
  103. int SDL_CondWaitTimeout(SDL_cond *cond, SDL_mutex *mutex, Uint32 ms)
  104. {
  105. int retval;
  106. struct timeval delta;
  107. struct timespec abstime;
  108. if ( ! cond ) {
  109. SDL_SetError("Passed a NULL condition variable");
  110. return -1;
  111. }
  112. gettimeofday(&delta, NULL);
  113. abstime.tv_sec = delta.tv_sec + (ms/1000);
  114. abstime.tv_nsec = (delta.tv_usec + (ms%1000) * 1000) * 1000;
  115.         if ( abstime.tv_nsec > 1000000000 ) {
  116.           abstime.tv_sec += 1;
  117.           abstime.tv_nsec -= 1000000000;
  118.         }
  119.   tryagain:
  120. retval = pthread_cond_timedwait(&cond->cond, &mutex->id, &abstime);
  121. switch (retval) {
  122.     case EINTR:
  123. goto tryagain;
  124. break;
  125.     case ETIMEDOUT:
  126. retval = SDL_MUTEX_TIMEDOUT;
  127. break;
  128.     case 0:
  129. break;
  130.     default:
  131. SDL_SetError("pthread_cond_timedwait() failed");
  132. retval = -1;
  133. break;
  134. }
  135. return retval;
  136. }
  137. /* Wait on the condition variable, unlocking the provided mutex.
  138.    The mutex must be locked before entering this function!
  139.  */
  140. int SDL_CondWait(SDL_cond *cond, SDL_mutex *mutex)
  141. {
  142. int retval;
  143. if ( ! cond ) {
  144. SDL_SetError("Passed a NULL condition variable");
  145. return -1;
  146. }
  147. retval = 0;
  148. if ( pthread_cond_wait(&cond->cond, &mutex->id) != 0 ) {
  149. SDL_SetError("pthread_cond_wait() failed");
  150. retval = -1;
  151. }
  152. return retval;
  153. }
  154. #else /* Use semaphore implementation */
  155. #include "generic/SDL_syscond.c"
  156. #endif /* SDL_USE_PTHREADS */