symbian-qemu-0.9.1-12/libsdl-trunk/src/thread/os2/SDL_syssem.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2     SDL - Simple DirectMedia Layer
       
     3     Copyright (C) 1997-2006 Sam Lantinga
       
     4 
       
     5     This library is free software; you can redistribute it and/or
       
     6     modify it under the terms of the GNU Lesser General Public
       
     7     License as published by the Free Software Foundation; either
       
     8     version 2.1 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     Lesser General Public License for more details.
       
    14 
       
    15     You should have received a copy of the GNU Lesser General Public
       
    16     License along with this library; if not, write to the Free Software
       
    17     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
       
    18 
       
    19     Sam Lantinga
       
    20     slouken@libsdl.org
       
    21 */
       
    22 #include "SDL_config.h"
       
    23 
       
    24 /* Semaphore functions using the OS/2 API */
       
    25 
       
    26 #define INCL_DOS
       
    27 #define INCL_DOSERRORS
       
    28 #define INCL_DOSSEMAPHORES
       
    29 #include <os2.h>
       
    30 
       
    31 #include "SDL_thread.h"
       
    32 #include "SDL_timer.h"
       
    33 
       
    34 
       
    35 struct SDL_semaphore {
       
    36         HMTX id;
       
    37         HEV  changed;
       
    38         Uint32 value;
       
    39 };
       
    40 
       
    41 
       
    42 /* Create a semaphore */
       
    43 DECLSPEC SDL_sem * SDLCALL SDL_CreateSemaphore(Uint32 initial_value)
       
    44 {
       
    45         SDL_sem *sem;
       
    46         ULONG ulrc;
       
    47 
       
    48         /* Allocate sem memory */
       
    49         sem = (SDL_sem *)SDL_malloc(sizeof(*sem));
       
    50         if ( sem ) {
       
    51                 /* Create the mutex semaphore */
       
    52                 ulrc = DosCreateMutexSem(NULL,&(sem->id),0,TRUE);
       
    53                 if ( ulrc ) {
       
    54                         SDL_SetError("Couldn't create semaphore");
       
    55                         SDL_free(sem);
       
    56                         sem = NULL;
       
    57                 } else
       
    58                 {
       
    59                     DosCreateEventSem(NULL, &(sem->changed), 0, FALSE);
       
    60                     sem->value = initial_value;
       
    61                     DosReleaseMutexSem(sem->id);
       
    62                 }
       
    63         } else {
       
    64                 SDL_OutOfMemory();
       
    65         }
       
    66         return(sem);
       
    67 }
       
    68 
       
    69 /* Free the semaphore */
       
    70 DECLSPEC void SDLCALL SDL_DestroySemaphore(SDL_sem *sem)
       
    71 {
       
    72         if ( sem ) {
       
    73                 if ( sem->id ) {
       
    74                         DosCloseEventSem(sem->changed);
       
    75                         DosCloseMutexSem(sem->id);
       
    76                         sem->id = 0;
       
    77                 }
       
    78                 SDL_free(sem);
       
    79         }
       
    80 }
       
    81 
       
    82 DECLSPEC int SDLCALL SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
       
    83 {
       
    84         ULONG ulrc;
       
    85 
       
    86         if ( ! sem ) {
       
    87                 SDL_SetError("Passed a NULL sem");
       
    88                 return -1;
       
    89         }
       
    90 
       
    91         if ( timeout == SDL_MUTEX_MAXWAIT ) {
       
    92            while (1) {
       
    93               ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT);
       
    94               if (ulrc) {
       
    95                  /* if error waiting mutex */
       
    96                  SDL_SetError("DosRequestMutexSem() failed");
       
    97                  return -1;
       
    98               } else if (sem->value) {
       
    99                         sem->value--;
       
   100                         DosReleaseMutexSem(sem->id);
       
   101                         return 0;
       
   102                      } else {
       
   103                         ULONG ulPostCount;
       
   104                         DosResetEventSem(sem->changed, &ulPostCount);
       
   105                         DosReleaseMutexSem(sem->id);
       
   106                         /* continue waiting until somebody posts the semaphore */
       
   107                         DosWaitEventSem(sem->changed, SEM_INDEFINITE_WAIT);
       
   108                      }
       
   109            }
       
   110         } else
       
   111         if ( timeout == 0 )
       
   112         {
       
   113             ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT);
       
   114             if (ulrc==NO_ERROR)
       
   115             {
       
   116                 if (sem->value)
       
   117                 {
       
   118                     sem->value--;
       
   119                     DosReleaseMutexSem(sem->id);
       
   120                     return 0;
       
   121                 } else
       
   122                 {
       
   123                     DosReleaseMutexSem(sem->id);
       
   124                     return SDL_MUTEX_TIMEDOUT;
       
   125                 }
       
   126             } else
       
   127             {
       
   128                 SDL_SetError("DosRequestMutexSem() failed");
       
   129                 return -1;
       
   130             }
       
   131         } else {
       
   132             ulrc = DosRequestMutexSem(sem->id, SEM_INDEFINITE_WAIT);
       
   133             if (ulrc) {
       
   134                /* if error waiting mutex */
       
   135                SDL_SetError("DosRequestMutexSem() failed");
       
   136                return -1;
       
   137             } else
       
   138               if (sem->value) {
       
   139                 sem->value--;
       
   140                 DosReleaseMutexSem(sem->id);
       
   141                 return 0;
       
   142               } else {
       
   143                 ULONG ulPostCount;
       
   144                 DosResetEventSem(sem->changed, &ulPostCount);
       
   145                 DosReleaseMutexSem(sem->id);
       
   146                 /* continue waiting until somebody posts the semaphore */
       
   147                 ulrc = DosWaitEventSem(sem->changed, timeout);
       
   148                 if (ulrc==NO_ERROR)
       
   149                   return 0;
       
   150                 else
       
   151                   return SDL_MUTEX_TIMEDOUT;
       
   152               }
       
   153         }
       
   154         /* never reached */
       
   155         return -1;
       
   156 }
       
   157 
       
   158 DECLSPEC int SDLCALL SDL_SemTryWait(SDL_sem *sem)
       
   159 {
       
   160         return SDL_SemWaitTimeout(sem, 0);
       
   161 }
       
   162 
       
   163 DECLSPEC int SDLCALL SDL_SemWait(SDL_sem *sem)
       
   164 {
       
   165         return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
       
   166 }
       
   167 
       
   168 /* Returns the current count of the semaphore */
       
   169 DECLSPEC Uint32 SDLCALL SDL_SemValue(SDL_sem *sem)
       
   170 {
       
   171         if ( ! sem ) {
       
   172                 SDL_SetError("Passed a NULL sem");
       
   173                 return 0;
       
   174         }
       
   175         return sem->value;
       
   176 }
       
   177 
       
   178 DECLSPEC int SDLCALL SDL_SemPost(SDL_sem *sem)
       
   179 {
       
   180         if ( ! sem ) {
       
   181                 SDL_SetError("Passed a NULL sem");
       
   182                 return -1;
       
   183         }
       
   184         if ( DosRequestMutexSem(sem->id,SEM_INDEFINITE_WAIT) ) {
       
   185                 SDL_SetError("DosRequestMutexSem() failed");
       
   186                 return -1;
       
   187         }
       
   188         sem->value++;
       
   189         DosPostEventSem(sem->changed);
       
   190         DosReleaseMutexSem(sem->id);
       
   191         return 0;
       
   192 }