Mercurial > sdl-ios-xcode
comparison src/thread/pthread/SDL_sysmutex.c @ 1361:19418e4422cb
New configure-based build system. Still work in progress, but much improved
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Thu, 16 Feb 2006 10:11:48 +0000 |
parents | |
children | d910939febfa |
comparison
equal
deleted
inserted
replaced
1360:70a9cfb4cf1b | 1361:19418e4422cb |
---|---|
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 | |
23 #include <pthread.h> | |
24 | |
25 #include "SDL_thread.h" | |
26 | |
27 #if !SDL_THREAD_PTHREAD_RECURSIVE_MUTEX && \ | |
28 !SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP | |
29 #define FAKE_RECURSIVE_MUTEX | |
30 #endif | |
31 | |
32 struct SDL_mutex { | |
33 pthread_mutex_t id; | |
34 #if FAKE_RECURSIVE_MUTEX | |
35 int recursive; | |
36 pthread_t owner; | |
37 #endif | |
38 }; | |
39 | |
40 SDL_mutex *SDL_CreateMutex (void) | |
41 { | |
42 SDL_mutex *mutex; | |
43 pthread_mutexattr_t attr; | |
44 | |
45 /* Allocate the structure */ | |
46 mutex = (SDL_mutex *)SDL_calloc(1, sizeof(*mutex)); | |
47 if ( mutex ) { | |
48 pthread_mutexattr_init(&attr); | |
49 #if SDL_THREAD_PTHREAD_RECURSIVE_MUTEX | |
50 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); | |
51 #elif SDL_THREAD_PTHREAD_RECURSIVE_MUTEX_NP | |
52 pthread_mutexattr_setkind_np(&attr, PTHREAD_MUTEX_RECURSIVE_NP); | |
53 #else | |
54 /* No extra attributes necessary */ | |
55 #endif | |
56 if ( pthread_mutex_init(&mutex->id, &attr) != 0 ) { | |
57 SDL_SetError("pthread_mutex_init() failed"); | |
58 SDL_free(mutex); | |
59 mutex = NULL; | |
60 } | |
61 } else { | |
62 SDL_OutOfMemory(); | |
63 } | |
64 return(mutex); | |
65 } | |
66 | |
67 void SDL_DestroyMutex(SDL_mutex *mutex) | |
68 { | |
69 if ( mutex ) { | |
70 pthread_mutex_destroy(&mutex->id); | |
71 SDL_free(mutex); | |
72 } | |
73 } | |
74 | |
75 /* Lock the mutex */ | |
76 int SDL_mutexP(SDL_mutex *mutex) | |
77 { | |
78 int retval; | |
79 #if FAKE_RECURSIVE_MUTEX | |
80 pthread_t this_thread; | |
81 #endif | |
82 | |
83 if ( mutex == NULL ) { | |
84 SDL_SetError("Passed a NULL mutex"); | |
85 return -1; | |
86 } | |
87 | |
88 retval = 0; | |
89 #if FAKE_RECURSIVE_MUTEX | |
90 this_thread = pthread_self(); | |
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 if ( pthread_mutex_lock(&mutex->id) == 0 ) { | |
99 mutex->owner = this_thread; | |
100 mutex->recursive = 0; | |
101 } else { | |
102 SDL_SetError("pthread_mutex_lock() failed"); | |
103 retval = -1; | |
104 } | |
105 } | |
106 #else | |
107 if ( pthread_mutex_lock(&mutex->id) < 0 ) { | |
108 SDL_SetError("pthread_mutex_lock() failed"); | |
109 retval = -1; | |
110 } | |
111 #endif | |
112 return retval; | |
113 } | |
114 | |
115 int SDL_mutexV(SDL_mutex *mutex) | |
116 { | |
117 int retval; | |
118 | |
119 if ( mutex == NULL ) { | |
120 SDL_SetError("Passed a NULL mutex"); | |
121 return -1; | |
122 } | |
123 | |
124 retval = 0; | |
125 #if FAKE_RECURSIVE_MUTEX | |
126 /* We can only unlock the mutex if we own it */ | |
127 if ( pthread_self() == mutex->owner ) { | |
128 if ( mutex->recursive ) { | |
129 --mutex->recursive; | |
130 } else { | |
131 /* The order of operations is important. | |
132 First reset the owner so another thread doesn't lock | |
133 the mutex and set the ownership before we reset it, | |
134 then release the lock semaphore. | |
135 */ | |
136 mutex->owner = 0; | |
137 pthread_mutex_unlock(&mutex->id); | |
138 } | |
139 } else { | |
140 SDL_SetError("mutex not owned by this thread"); | |
141 retval = -1; | |
142 } | |
143 | |
144 #else | |
145 if ( pthread_mutex_unlock(&mutex->id) < 0 ) { | |
146 SDL_SetError("pthread_mutex_unlock() failed"); | |
147 retval = -1; | |
148 } | |
149 #endif /* FAKE_RECURSIVE_MUTEX */ | |
150 | |
151 return retval; | |
152 } |