Mercurial > sdl-ios-xcode
comparison src/thread/windows/SDL_syssem.c @ 5062:e8916fe9cfc8
Fixed bug #925
Changed "win32" to "windows"
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Thu, 20 Jan 2011 18:04:05 -0800 |
parents | src/thread/win32/SDL_syssem.c@883a2f2ff43f |
children | c2539ff054c8 |
comparison
equal
deleted
inserted
replaced
5061:9e9940eae455 | 5062:e8916fe9cfc8 |
---|---|
1 /* | |
2 SDL - Simple DirectMedia Layer | |
3 Copyright (C) 1997-2010 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 Win32 API */ | |
25 | |
26 #define WIN32_LEAN_AND_MEAN | |
27 #include <windows.h> | |
28 | |
29 #include "SDL_thread.h" | |
30 #if defined(_WIN32_WCE) && (_WIN32_WCE < 300) | |
31 #include "win_ce_semaphore.h" | |
32 #endif | |
33 | |
34 | |
35 struct SDL_semaphore | |
36 { | |
37 #if defined(_WIN32_WCE) && (_WIN32_WCE < 300) | |
38 SYNCHHANDLE id; | |
39 #else | |
40 HANDLE id; | |
41 #endif | |
42 LONG volatile count; | |
43 }; | |
44 | |
45 | |
46 /* Create a semaphore */ | |
47 SDL_sem * | |
48 SDL_CreateSemaphore(Uint32 initial_value) | |
49 { | |
50 SDL_sem *sem; | |
51 | |
52 /* Allocate sem memory */ | |
53 sem = (SDL_sem *) SDL_malloc(sizeof(*sem)); | |
54 if (sem) { | |
55 /* Create the semaphore, with max value 32K */ | |
56 #if defined(_WIN32_WCE) && (_WIN32_WCE < 300) | |
57 sem->id = CreateSemaphoreCE(NULL, initial_value, 32 * 1024, NULL); | |
58 #else | |
59 sem->id = CreateSemaphore(NULL, initial_value, 32 * 1024, NULL); | |
60 #endif | |
61 sem->count = initial_value; | |
62 if (!sem->id) { | |
63 SDL_SetError("Couldn't create semaphore"); | |
64 SDL_free(sem); | |
65 sem = NULL; | |
66 } | |
67 } else { | |
68 SDL_OutOfMemory(); | |
69 } | |
70 return (sem); | |
71 } | |
72 | |
73 /* Free the semaphore */ | |
74 void | |
75 SDL_DestroySemaphore(SDL_sem * sem) | |
76 { | |
77 if (sem) { | |
78 if (sem->id) { | |
79 #if defined(_WIN32_WCE) && (_WIN32_WCE < 300) | |
80 CloseSynchHandle(sem->id); | |
81 #else | |
82 CloseHandle(sem->id); | |
83 #endif | |
84 sem->id = 0; | |
85 } | |
86 SDL_free(sem); | |
87 } | |
88 } | |
89 | |
90 int | |
91 SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout) | |
92 { | |
93 int retval; | |
94 DWORD dwMilliseconds; | |
95 | |
96 if (!sem) { | |
97 SDL_SetError("Passed a NULL sem"); | |
98 return -1; | |
99 } | |
100 | |
101 if (timeout == SDL_MUTEX_MAXWAIT) { | |
102 dwMilliseconds = INFINITE; | |
103 } else { | |
104 dwMilliseconds = (DWORD) timeout; | |
105 } | |
106 #if defined(_WIN32_WCE) && (_WIN32_WCE < 300) | |
107 switch (WaitForSemaphoreCE(sem->id, dwMilliseconds)) { | |
108 #else | |
109 switch (WaitForSingleObject(sem->id, dwMilliseconds)) { | |
110 #endif | |
111 case WAIT_OBJECT_0: | |
112 InterlockedDecrement(&sem->count); | |
113 retval = 0; | |
114 break; | |
115 case WAIT_TIMEOUT: | |
116 retval = SDL_MUTEX_TIMEDOUT; | |
117 break; | |
118 default: | |
119 SDL_SetError("WaitForSingleObject() failed"); | |
120 retval = -1; | |
121 break; | |
122 } | |
123 return retval; | |
124 } | |
125 | |
126 int | |
127 SDL_SemTryWait(SDL_sem * sem) | |
128 { | |
129 return SDL_SemWaitTimeout(sem, 0); | |
130 } | |
131 | |
132 int | |
133 SDL_SemWait(SDL_sem * sem) | |
134 { | |
135 return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); | |
136 } | |
137 | |
138 /* Returns the current count of the semaphore */ | |
139 Uint32 | |
140 SDL_SemValue(SDL_sem * sem) | |
141 { | |
142 if (!sem) { | |
143 SDL_SetError("Passed a NULL sem"); | |
144 return 0; | |
145 } | |
146 return (Uint32)sem->count; | |
147 } | |
148 | |
149 int | |
150 SDL_SemPost(SDL_sem * sem) | |
151 { | |
152 if (!sem) { | |
153 SDL_SetError("Passed a NULL sem"); | |
154 return -1; | |
155 } | |
156 /* Increase the counter in the first place, because | |
157 * after a successful release the semaphore may | |
158 * immediately get destroyed by another thread which | |
159 * is waiting for this semaphore. | |
160 */ | |
161 InterlockedIncrement(&sem->count); | |
162 #if defined(_WIN32_WCE) && (_WIN32_WCE < 300) | |
163 if (ReleaseSemaphoreCE(sem->id, 1, NULL) == FALSE) { | |
164 #else | |
165 if (ReleaseSemaphore(sem->id, 1, NULL) == FALSE) { | |
166 #endif | |
167 InterlockedDecrement(&sem->count); /* restore */ | |
168 SDL_SetError("ReleaseSemaphore() failed"); | |
169 return -1; | |
170 } | |
171 return 0; | |
172 } | |
173 | |
174 /* vi: set ts=4 sw=4 expandtab: */ |