src/thread/generic/SDL_sysmutex.c

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

FUNCTIONS

This source file includes following functions.
  1. SDL_CreateMutex
  2. SDL_DestroyMutex
  3. SDL_mutexP
  4. SDL_mutexV

   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_sysmutex.c,v 1.1.2.7 2001/02/10 07:20:04 hercules Exp $";
  26 #endif
  27 
  28 /* An implementation of mutexes using semaphores */
  29 
  30 #include <stdio.h>
  31 #include <stdlib.h>
  32 
  33 #include "SDL_error.h"
  34 #include "SDL_thread.h"
  35 #include "SDL_systhread_c.h"
  36 
  37 
  38 struct SDL_mutex {
  39         int recursive;
  40         Uint32 owner;
  41         SDL_sem *sem;
  42 };
  43 
  44 /* Create a mutex */
  45 SDL_mutex *SDL_CreateMutex(void)
     /* [<][>][^][v][top][bottom][index][help] */
  46 {
  47         SDL_mutex *mutex;
  48 
  49         /* Allocate mutex memory */
  50         mutex = (SDL_mutex *)malloc(sizeof(*mutex));
  51         if ( mutex ) {
  52                 /* Create the mutex semaphore, with initial value 1 */
  53                 mutex->sem = SDL_CreateSemaphore(1);
  54                 mutex->recursive = 0;
  55                 mutex->owner = 0;
  56                 if ( ! mutex->sem ) {
  57                         free(mutex);
  58                         mutex = NULL;
  59                 }
  60         } else {
  61                 SDL_OutOfMemory();
  62         }
  63         return mutex;
  64 }
  65 
  66 /* Free the mutex */
  67 void SDL_DestroyMutex(SDL_mutex *mutex)
     /* [<][>][^][v][top][bottom][index][help] */
  68 {
  69         if ( mutex ) {
  70                 if ( mutex->sem ) {
  71                         SDL_DestroySemaphore(mutex->sem);
  72                 }
  73                 free(mutex);
  74         }
  75 }
  76 
  77 /* Lock the semaphore */
  78 int SDL_mutexP(SDL_mutex *mutex)
     /* [<][>][^][v][top][bottom][index][help] */
  79 {
  80 #ifdef DISABLE_THREADS
  81         return 0;
  82 #else
  83         Uint32 this_thread;
  84 
  85         if ( mutex == NULL ) {
  86                 SDL_SetError("Passed a NULL mutex");
  87                 return -1;
  88         }
  89 
  90         this_thread = SDL_ThreadID();
  91         if ( mutex->owner == this_thread ) {
  92                 ++mutex->recursive;
  93         } else {
  94                 /* The order of operations is important.
  95                    We set the locking thread id after we obtain the lock
  96                    so unlocks from other threads will fail.
  97                 */
  98                 SDL_SemWait(mutex->sem);
  99                 mutex->owner = this_thread;
 100                 mutex->recursive = 0;
 101         }
 102 
 103         return 0;
 104 #endif /* DISABLE_THREADS */
 105 }
 106 
 107 /* Unlock the mutex */
 108 int SDL_mutexV(SDL_mutex *mutex)
     /* [<][>][^][v][top][bottom][index][help] */
 109 {
 110 #ifdef DISABLE_THREADS
 111         return 0;
 112 #else
 113         if ( mutex == NULL ) {
 114                 SDL_SetError("Passed a NULL mutex");
 115                 return -1;
 116         }
 117 
 118         /* If we don't own the mutex, we can't unlock it */
 119         if ( SDL_ThreadID() != mutex->owner ) {
 120                 SDL_SetError("mutex not owned by this thread");
 121                 return -1;
 122         }
 123 
 124         if ( mutex->recursive ) {
 125                 --mutex->recursive;
 126         } else {
 127                 /* The order of operations is important.
 128                    First reset the owner so another thread doesn't lock
 129                    the mutex and set the ownership before we reset it,
 130                    then release the lock semaphore.
 131                  */
 132                 mutex->owner = 0;
 133                 SDL_SemPost(mutex->sem);
 134         }
 135         return 0;
 136 #endif /* DISABLE_THREADS */
 137 }

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