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

流媒体/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_syssem.c,v 1.4 2002/04/22 21:38:03 wmay Exp $";
  21. #endif
  22. /* An implementation of semaphores using mutexes and condition variables */
  23. #include <stdlib.h>
  24. #include "SDL_error.h"
  25. #include "SDL_timer.h"
  26. #include "SDL_thread.h"
  27. #include "SDL_systhread_c.h"
  28. #ifdef DISABLE_THREADS
  29. SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
  30. {
  31. SDL_SetError("SDL not configured with thread support");
  32. return (SDL_sem *)0;
  33. }
  34. void SDL_DestroySemaphore(SDL_sem *sem)
  35. {
  36. return;
  37. }
  38. int SDL_SemTryWait(SDL_sem *sem)
  39. {
  40. SDL_SetError("SDL not configured with thread support");
  41. return -1;
  42. }
  43. int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
  44. {
  45. SDL_SetError("SDL not configured with thread support");
  46. return -1;
  47. }
  48. int SDL_SemWait(SDL_sem *sem)
  49. {
  50. SDL_SetError("SDL not configured with thread support");
  51. return -1;
  52. }
  53. Uint32 SDL_SemValue(SDL_sem *sem)
  54. {
  55. return 0;
  56. }
  57. int SDL_SemPost(SDL_sem *sem)
  58. {
  59. SDL_SetError("SDL not configured with thread support");
  60. return -1;
  61. }
  62. #else
  63. struct SDL_semaphore
  64. {
  65. Uint32 count;
  66. Uint32 waiters_count;
  67. SDL_mutex *count_lock;
  68. SDL_cond *count_nonzero;
  69. };
  70. SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
  71. {
  72. SDL_sem *sem;
  73. sem = (SDL_sem *)malloc(sizeof(*sem));
  74. if ( ! sem ) {
  75. SDL_OutOfMemory();
  76. return(0);
  77. }
  78. sem->count = initial_value;
  79. sem->waiters_count = 0;
  80. sem->count_lock = SDL_CreateMutex();
  81. sem->count_nonzero = SDL_CreateCond();
  82. if ( ! sem->count_lock || ! sem->count_nonzero ) {
  83. SDL_DestroySemaphore(sem);
  84. return(0);
  85. }
  86. return(sem);
  87. }
  88. /* WARNING:
  89.    You cannot call this function when another thread is using the semaphore.
  90. */
  91. void SDL_DestroySemaphore(SDL_sem *sem)
  92. {
  93. if ( sem ) {
  94. sem->count = 0xFFFFFFFF;
  95. while ( sem->waiters_count > 0) {
  96. SDL_CondSignal(sem->count_nonzero);
  97. SDL_Delay(10);
  98. }
  99. SDL_DestroyCond(sem->count_nonzero);
  100. SDL_mutexP(sem->count_lock);
  101. SDL_mutexV(sem->count_lock);
  102. SDL_DestroyMutex(sem->count_lock);
  103. free(sem);
  104. }
  105. }
  106. int SDL_SemTryWait(SDL_sem *sem)
  107. {
  108. int retval;
  109. if ( ! sem ) {
  110. SDL_SetError("Passed a NULL semaphore");
  111. return -1;
  112. }
  113. retval = SDL_MUTEX_TIMEDOUT;
  114. SDL_LockMutex(sem->count_lock);
  115. if ( sem->count > 0 ) {
  116. --sem->count;
  117. retval = 0;
  118. }
  119. SDL_UnlockMutex(sem->count_lock);
  120. return retval;
  121. }
  122. int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
  123. {
  124. int retval;
  125. if ( ! sem ) {
  126. SDL_SetError("Passed a NULL semaphore");
  127. return -1;
  128. }
  129. /* A timeout of 0 is an easy case */
  130. if ( timeout == 0 ) {
  131. return SDL_SemTryWait(sem);
  132. }
  133. SDL_LockMutex(sem->count_lock);
  134. ++sem->waiters_count;
  135. retval = 0;
  136. while ( (sem->count == 0) && (retval != SDL_MUTEX_TIMEDOUT) ) {
  137. retval = SDL_CondWaitTimeout(sem->count_nonzero,
  138.                              sem->count_lock, timeout);
  139. }
  140. --sem->waiters_count;
  141. --sem->count;
  142. SDL_UnlockMutex(sem->count_lock);
  143. return retval;
  144. }
  145. int SDL_SemWait(SDL_sem *sem)
  146. {
  147. return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
  148. }
  149. Uint32 SDL_SemValue(SDL_sem *sem)
  150. {
  151. Uint32 value;
  152. value = 0;
  153. if ( sem ) {
  154. SDL_LockMutex(sem->count_lock);
  155. value = sem->count;
  156. SDL_UnlockMutex(sem->count_lock);
  157. }
  158. return value;
  159. }
  160. int SDL_SemPost(SDL_sem *sem)
  161. {
  162. if ( ! sem ) {
  163. SDL_SetError("Passed a NULL semaphore");
  164. return -1;
  165. }
  166. SDL_LockMutex(sem->count_lock);
  167. if ( sem->waiters_count > 0 ) {
  168. SDL_CondSignal(sem->count_nonzero);
  169. }
  170. ++sem->count;
  171. SDL_UnlockMutex(sem->count_lock);
  172. return 0;
  173. }
  174. #endif /* DISABLE_THREADS */