src/thread/win32/SDL_syssem.c

/* [<][>]
[^][v][top][bottom][index][help] */

FUNCTIONS

This source file includes following functions.
  1. SDL_CreateSemaphore
  2. SDL_DestroySemaphore
  3. SDL_SemWaitTimeout
  4. SDL_SemTryWait
  5. SDL_SemWait
  6. SDL_SemValue
  7. SDL_SemPost
  8. SDL_CreateSemaphore
  9. SDL_DestroySemaphore
  10. SDL_SemWaitTimeout
  11. SDL_SemTryWait
  12. SDL_SemWait
  13. SDL_SemValue
  14. SDL_SemPost

   1 /*
   2     SDL - Simple DirectMedia Layer
   3     Copyright (C) 1997, 1998, 1999, 2000, 2001  Sam Lantinga
   4 
   5     This library is free software; you can redistribute it and/or
   6     modify it under the terms of the GNU Library General Public
   7     License as published by the Free Software Foundation; either
   8     version 2 of the License, or (at your option) any later version.
   9 
  10     This library is distributed in the hope that it will be useful,
  11     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13     Library General Public License for more details.
  14 
  15     You should have received a copy of the GNU Library General Public
  16     License along with this library; if not, write to the Free
  17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18 
  19     Sam Lantinga
  20     slouken@devolution.com
  21 */
  22 
  23 #ifdef SAVE_RCSID
  24 static char rcsid =
  25  "@(#) $Id: SDL_syssem.c,v 1.1.2.6 2001/02/10 07:20:04 hercules Exp $";
  26 #endif
  27 
  28 /* Semaphore functions using the Win32 API */
  29 
  30 #include <stdio.h>
  31 #include <stdlib.h>
  32 #include <windows.h>
  33 
  34 #include "SDL_error.h"
  35 #include "SDL_thread.h"
  36 
  37 #if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
  38 
  39 /* No semaphores on Windows CE earlier than 3.0, hmm... */
  40 
  41 /* Create a semaphore */
  42 SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
     /* [<][>][^][v][top][bottom][index][help] */
  43 {
  44         SDL_SetError("Semaphores not supported on WinCE");
  45         return(NULL);
  46 }
  47 
  48 /* Free the semaphore */
  49 void SDL_DestroySemaphore(SDL_sem *sem)
     /* [<][>][^][v][top][bottom][index][help] */
  50 {
  51         return;
  52 }
  53 
  54 int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
     /* [<][>][^][v][top][bottom][index][help] */
  55 {
  56         SDL_SetError("Semaphores not supported on WinCE");
  57         return(-1);
  58 }
  59 
  60 int SDL_SemTryWait(SDL_sem *sem)
     /* [<][>][^][v][top][bottom][index][help] */
  61 {
  62         return SDL_SemWaitTimeout(sem, 0);
  63 }
  64 
  65 int SDL_SemWait(SDL_sem *sem)
     /* [<][>][^][v][top][bottom][index][help] */
  66 {
  67         return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
  68 }
  69 
  70 /* Returns the current count of the semaphore */
  71 Uint32 SDL_SemValue(SDL_sem *sem)
     /* [<][>][^][v][top][bottom][index][help] */
  72 {
  73         return(0);
  74 }
  75 
  76 int SDL_SemPost(SDL_sem *sem)
     /* [<][>][^][v][top][bottom][index][help] */
  77 {
  78         SDL_SetError("Semaphores not supported on WinCE");
  79         return(-1);
  80 }
  81 
  82 #else
  83 
  84 struct SDL_semaphore {
  85         HANDLE id;
  86         Uint32 volatile count;
  87 };
  88 
  89 
  90 /* Create a semaphore */
  91 SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
     /* [<][>][^][v][top][bottom][index][help] */
  92 {
  93         SDL_sem *sem;
  94 
  95         /* Allocate sem memory */
  96         sem = (SDL_sem *)malloc(sizeof(*sem));
  97         if ( sem ) {
  98                 /* Create the semaphore, with max value 32K */
  99                 sem->id = CreateSemaphore(NULL, initial_value, 32*1024, NULL);
 100                 sem->count = initial_value;
 101                 if ( ! sem->id ) {
 102                         SDL_SetError("Couldn't create semaphore");
 103                         free(sem);
 104                         sem = NULL;
 105                 }
 106         } else {
 107                 SDL_OutOfMemory();
 108         }
 109         return(sem);
 110 }
 111 
 112 /* Free the semaphore */
 113 void SDL_DestroySemaphore(SDL_sem *sem)
     /* [<][>][^][v][top][bottom][index][help] */
 114 {
 115         if ( sem ) {
 116                 if ( sem->id ) {
 117                         CloseHandle(sem->id);
 118                         sem->id = 0;
 119                 }
 120                 free(sem);
 121         }
 122 }
 123 
 124 int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
     /* [<][>][^][v][top][bottom][index][help] */
 125 {
 126         int retval;
 127         DWORD dwMilliseconds;
 128 
 129         if ( ! sem ) {
 130                 SDL_SetError("Passed a NULL sem");
 131                 return -1;
 132         }
 133 
 134         if ( timeout == SDL_MUTEX_MAXWAIT ) {
 135                 dwMilliseconds = INFINITE;
 136         } else {
 137                 dwMilliseconds = (DWORD)timeout;
 138         }
 139         switch (WaitForSingleObject(sem->id, dwMilliseconds)) {
 140             case WAIT_OBJECT_0:
 141                 --sem->count;
 142                 retval = 0;
 143                 break;
 144             case WAIT_TIMEOUT:
 145                 retval = SDL_MUTEX_TIMEDOUT;
 146                 break;
 147             default:
 148                 SDL_SetError("WaitForSingleObject() failed");
 149                 retval = -1;
 150                 break;
 151         }
 152         return retval;
 153 }
 154 
 155 int SDL_SemTryWait(SDL_sem *sem)
     /* [<][>][^][v][top][bottom][index][help] */
 156 {
 157         return SDL_SemWaitTimeout(sem, 0);
 158 }
 159 
 160 int SDL_SemWait(SDL_sem *sem)
     /* [<][>][^][v][top][bottom][index][help] */
 161 {
 162         return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
 163 }
 164 
 165 /* Returns the current count of the semaphore */
 166 Uint32 SDL_SemValue(SDL_sem *sem)
     /* [<][>][^][v][top][bottom][index][help] */
 167 {
 168         if ( ! sem ) {
 169                 SDL_SetError("Passed a NULL sem");
 170                 return 0;
 171         }
 172         return sem->count;
 173 }
 174 
 175 int SDL_SemPost(SDL_sem *sem)
     /* [<][>][^][v][top][bottom][index][help] */
 176 {
 177         if ( ! sem ) {
 178                 SDL_SetError("Passed a NULL sem");
 179                 return -1;
 180         }
 181         /* Increase the counter in the first place, because
 182          * after a successful release the semaphore may
 183          * immediately get destroyed by another thread which
 184          * is waiting for this semaphore.
 185          */
 186         ++sem->count;
 187         if ( ReleaseSemaphore(sem->id, 1, NULL) == FALSE ) {
 188                 --sem->count;   /* restore */
 189                 SDL_SetError("ReleaseSemaphore() failed");
 190                 return -1;
 191         }
 192         return 0;
 193 }
 194 
 195 #endif /* _WIN32_WCE */

/* [<][>][^][v][top][bottom][index][help] */