author | David Ludwig |
Thu, 22 Nov 2012 23:12:06 -0500 | |
changeset 8357 | 8d788bb003f2 |
parent 8356 | src/thread/stdcpp/SDL_sysmutex.c@4d85eba58f0a |
child 8360 | 7f1bc00e59fc |
permissions | -rw-r--r-- |
dludwig@8356 | 1 |
/* |
dludwig@8356 | 2 |
Simple DirectMedia Layer |
dludwig@8356 | 3 |
Copyright (C) 1997-2012 Sam Lantinga <slouken@libsdl.org> |
dludwig@8356 | 4 |
|
dludwig@8356 | 5 |
This software is provided 'as-is', without any express or implied |
dludwig@8356 | 6 |
warranty. In no event will the authors be held liable for any damages |
dludwig@8356 | 7 |
arising from the use of this software. |
dludwig@8356 | 8 |
|
dludwig@8356 | 9 |
Permission is granted to anyone to use this software for any purpose, |
dludwig@8356 | 10 |
including commercial applications, and to alter it and redistribute it |
dludwig@8356 | 11 |
freely, subject to the following restrictions: |
dludwig@8356 | 12 |
|
dludwig@8356 | 13 |
1. The origin of this software must not be misrepresented; you must not |
dludwig@8356 | 14 |
claim that you wrote the original software. If you use this software |
dludwig@8356 | 15 |
in a product, an acknowledgment in the product documentation would be |
dludwig@8356 | 16 |
appreciated but is not required. |
dludwig@8356 | 17 |
2. Altered source versions must be plainly marked as such, and must not be |
dludwig@8356 | 18 |
misrepresented as being the original software. |
dludwig@8356 | 19 |
3. This notice may not be removed or altered from any source distribution. |
dludwig@8356 | 20 |
*/ |
dludwig@8356 | 21 |
#include "SDL_config.h" |
dludwig@8356 | 22 |
|
dludwig@8356 | 23 |
/* An implementation of mutexes using semaphores */ |
dludwig@8356 | 24 |
|
dludwig@8356 | 25 |
#include "SDL_thread.h" |
dludwig@8356 | 26 |
#include "SDL_systhread_c.h" |
dludwig@8356 | 27 |
|
dludwig@8356 | 28 |
|
dludwig@8356 | 29 |
struct SDL_mutex |
dludwig@8356 | 30 |
{ |
dludwig@8356 | 31 |
int recursive; |
dludwig@8356 | 32 |
SDL_threadID owner; |
dludwig@8356 | 33 |
SDL_sem *sem; |
dludwig@8356 | 34 |
}; |
dludwig@8356 | 35 |
|
dludwig@8356 | 36 |
/* Create a mutex */ |
dludwig@8357 | 37 |
extern "C" |
dludwig@8356 | 38 |
SDL_mutex * |
dludwig@8356 | 39 |
SDL_CreateMutex(void) |
dludwig@8356 | 40 |
{ |
dludwig@8356 | 41 |
SDL_mutex *mutex; |
dludwig@8356 | 42 |
|
dludwig@8356 | 43 |
/* Allocate mutex memory */ |
dludwig@8356 | 44 |
mutex = (SDL_mutex *) SDL_malloc(sizeof(*mutex)); |
dludwig@8356 | 45 |
if (mutex) { |
dludwig@8356 | 46 |
/* Create the mutex semaphore, with initial value 1 */ |
dludwig@8356 | 47 |
mutex->sem = SDL_CreateSemaphore(1); |
dludwig@8356 | 48 |
mutex->recursive = 0; |
dludwig@8356 | 49 |
mutex->owner = 0; |
dludwig@8356 | 50 |
if (!mutex->sem) { |
dludwig@8356 | 51 |
SDL_free(mutex); |
dludwig@8356 | 52 |
mutex = NULL; |
dludwig@8356 | 53 |
} |
dludwig@8356 | 54 |
} else { |
dludwig@8356 | 55 |
SDL_OutOfMemory(); |
dludwig@8356 | 56 |
} |
dludwig@8356 | 57 |
return mutex; |
dludwig@8356 | 58 |
} |
dludwig@8356 | 59 |
|
dludwig@8356 | 60 |
/* Free the mutex */ |
dludwig@8357 | 61 |
extern "C" |
dludwig@8356 | 62 |
void |
dludwig@8356 | 63 |
SDL_DestroyMutex(SDL_mutex * mutex) |
dludwig@8356 | 64 |
{ |
dludwig@8356 | 65 |
if (mutex) { |
dludwig@8356 | 66 |
if (mutex->sem) { |
dludwig@8356 | 67 |
SDL_DestroySemaphore(mutex->sem); |
dludwig@8356 | 68 |
} |
dludwig@8356 | 69 |
SDL_free(mutex); |
dludwig@8356 | 70 |
} |
dludwig@8356 | 71 |
} |
dludwig@8356 | 72 |
|
dludwig@8356 | 73 |
/* Lock the semaphore */ |
dludwig@8357 | 74 |
extern "C" |
dludwig@8356 | 75 |
int |
dludwig@8356 | 76 |
SDL_mutexP(SDL_mutex * mutex) |
dludwig@8356 | 77 |
{ |
dludwig@8356 | 78 |
#if SDL_THREADS_DISABLED |
dludwig@8356 | 79 |
return 0; |
dludwig@8356 | 80 |
#else |
dludwig@8356 | 81 |
SDL_threadID this_thread; |
dludwig@8356 | 82 |
|
dludwig@8356 | 83 |
if (mutex == NULL) { |
dludwig@8356 | 84 |
SDL_SetError("Passed a NULL mutex"); |
dludwig@8356 | 85 |
return -1; |
dludwig@8356 | 86 |
} |
dludwig@8356 | 87 |
|
dludwig@8356 | 88 |
this_thread = SDL_ThreadID(); |
dludwig@8356 | 89 |
if (mutex->owner == this_thread) { |
dludwig@8356 | 90 |
++mutex->recursive; |
dludwig@8356 | 91 |
} else { |
dludwig@8356 | 92 |
/* The order of operations is important. |
dludwig@8356 | 93 |
We set the locking thread id after we obtain the lock |
dludwig@8356 | 94 |
so unlocks from other threads will fail. |
dludwig@8356 | 95 |
*/ |
dludwig@8356 | 96 |
SDL_SemWait(mutex->sem); |
dludwig@8356 | 97 |
mutex->owner = this_thread; |
dludwig@8356 | 98 |
mutex->recursive = 0; |
dludwig@8356 | 99 |
} |
dludwig@8356 | 100 |
|
dludwig@8356 | 101 |
return 0; |
dludwig@8356 | 102 |
#endif /* SDL_THREADS_DISABLED */ |
dludwig@8356 | 103 |
} |
dludwig@8356 | 104 |
|
dludwig@8356 | 105 |
/* Unlock the mutex */ |
dludwig@8357 | 106 |
extern "C" |
dludwig@8356 | 107 |
int |
dludwig@8356 | 108 |
SDL_mutexV(SDL_mutex * mutex) |
dludwig@8356 | 109 |
{ |
dludwig@8356 | 110 |
#if SDL_THREADS_DISABLED |
dludwig@8356 | 111 |
return 0; |
dludwig@8356 | 112 |
#else |
dludwig@8356 | 113 |
if (mutex == NULL) { |
dludwig@8356 | 114 |
SDL_SetError("Passed a NULL mutex"); |
dludwig@8356 | 115 |
return -1; |
dludwig@8356 | 116 |
} |
dludwig@8356 | 117 |
|
dludwig@8356 | 118 |
/* If we don't own the mutex, we can't unlock it */ |
dludwig@8356 | 119 |
if (SDL_ThreadID() != mutex->owner) { |
dludwig@8356 | 120 |
SDL_SetError("mutex not owned by this thread"); |
dludwig@8356 | 121 |
return -1; |
dludwig@8356 | 122 |
} |
dludwig@8356 | 123 |
|
dludwig@8356 | 124 |
if (mutex->recursive) { |
dludwig@8356 | 125 |
--mutex->recursive; |
dludwig@8356 | 126 |
} else { |
dludwig@8356 | 127 |
/* The order of operations is important. |
dludwig@8356 | 128 |
First reset the owner so another thread doesn't lock |
dludwig@8356 | 129 |
the mutex and set the ownership before we reset it, |
dludwig@8356 | 130 |
then release the lock semaphore. |
dludwig@8356 | 131 |
*/ |
dludwig@8356 | 132 |
mutex->owner = 0; |
dludwig@8356 | 133 |
SDL_SemPost(mutex->sem); |
dludwig@8356 | 134 |
} |
dludwig@8356 | 135 |
return 0; |
dludwig@8356 | 136 |
#endif /* SDL_THREADS_DISABLED */ |
dludwig@8356 | 137 |
} |
dludwig@8356 | 138 |
|
dludwig@8356 | 139 |
/* vi: set ts=4 sw=4 expandtab: */ |