src/thread/generic/SDL_sysmutex.c
author Sam Lantinga <slouken@libsdl.org>
Mon, 29 May 2006 04:04:35 +0000
branchSDL-1.3
changeset 1668 4da1ee79c9af
parent 1662 782fd950bd46
permissions -rw-r--r--
more tweaking indent options
     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 /* An implementation of mutexes using semaphores */
    25 
    26 #include "SDL_thread.h"
    27 #include "SDL_systhread_c.h"
    28 
    29 
    30 struct SDL_mutex
    31 {
    32     int recursive;
    33     Uint32 owner;
    34     SDL_sem *sem;
    35 };
    36 
    37 /* Create a mutex */
    38 SDL_mutex *
    39 SDL_CreateMutex(void)
    40 {
    41     SDL_mutex *mutex;
    42 
    43     /* Allocate mutex memory */
    44     mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex));
    45     if (mutex) {
    46         /* Create the mutex semaphore, with initial value 1 */
    47         mutex->sem = SDL_CreateSemaphore(1);
    48         mutex->recursive = 0;
    49         mutex->owner = 0;
    50         if (!mutex->sem) {
    51             SDL_free(mutex);
    52             mutex = NULL;
    53         }
    54     } else {
    55         SDL_OutOfMemory();
    56     }
    57     return mutex;
    58 }
    59 
    60 /* Free the mutex */
    61 void
    62 SDL_DestroyMutex(SDL_mutex * mutex)
    63 {
    64     if (mutex) {
    65         if (mutex->sem) {
    66             SDL_DestroySemaphore(mutex->sem);
    67         }
    68         SDL_free(mutex);
    69     }
    70 }
    71 
    72 /* Lock the semaphore */
    73 int
    74 SDL_mutexP(SDL_mutex * mutex)
    75 {
    76 #if SDL_THREADS_DISABLED
    77     return 0;
    78 #else
    79     Uint32 this_thread;
    80 
    81     if (mutex == NULL) {
    82         SDL_SetError("Passed a NULL mutex");
    83         return -1;
    84     }
    85 
    86     this_thread = SDL_ThreadID();
    87     if (mutex->owner == this_thread) {
    88         ++mutex->recursive;
    89     } else {
    90         /* The order of operations is important.
    91            We set the locking thread id after we obtain the lock
    92            so unlocks from other threads will fail.
    93          */
    94         SDL_SemWait(mutex->sem);
    95         mutex->owner = this_thread;
    96         mutex->recursive = 0;
    97     }
    98 
    99     return 0;
   100 #endif /* SDL_THREADS_DISABLED */
   101 }
   102 
   103 /* Unlock the mutex */
   104 int
   105 SDL_mutexV(SDL_mutex * mutex)
   106 {
   107 #if SDL_THREADS_DISABLED
   108     return 0;
   109 #else
   110     if (mutex == NULL) {
   111         SDL_SetError("Passed a NULL mutex");
   112         return -1;
   113     }
   114 
   115     /* If we don't own the mutex, we can't unlock it */
   116     if (SDL_ThreadID() != mutex->owner) {
   117         SDL_SetError("mutex not owned by this thread");
   118         return -1;
   119     }
   120 
   121     if (mutex->recursive) {
   122         --mutex->recursive;
   123     } else {
   124         /* The order of operations is important.
   125            First reset the owner so another thread doesn't lock
   126            the mutex and set the ownership before we reset it,
   127            then release the lock semaphore.
   128          */
   129         mutex->owner = 0;
   130         SDL_SemPost(mutex->sem);
   131     }
   132     return 0;
   133 #endif /* SDL_THREADS_DISABLED */
   134 }
   135 
   136 /* vi: set ts=4 sw=4 expandtab: */