comparison src/thread/win32/SDL_syssem.c @ 0:74212992fb08

Initial revision
author Sam Lantinga <slouken@lokigames.com>
date Thu, 26 Apr 2001 16:45:43 +0000
parents
children 13ee9f4834ea
comparison
equal deleted inserted replaced
-1:000000000000 0:74212992fb08
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$";
26 #endif
27
28 /* Semaphore functions using the Win32 API */
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <windows.h>
33
34 #include "SDL_error.h"
35 #include "SDL_thread.h"
36
37 #if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
38
39 /* No semaphores on Windows CE earlier than 3.0, hmm... */
40
41 /* Create a semaphore */
42 SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
43 {
44 SDL_SetError("Semaphores not supported on WinCE");
45 return(NULL);
46 }
47
48 /* Free the semaphore */
49 void SDL_DestroySemaphore(SDL_sem *sem)
50 {
51 return;
52 }
53
54 int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
55 {
56 SDL_SetError("Semaphores not supported on WinCE");
57 return(-1);
58 }
59
60 int SDL_SemTryWait(SDL_sem *sem)
61 {
62 return SDL_SemWaitTimeout(sem, 0);
63 }
64
65 int SDL_SemWait(SDL_sem *sem)
66 {
67 return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
68 }
69
70 /* Returns the current count of the semaphore */
71 Uint32 SDL_SemValue(SDL_sem *sem)
72 {
73 return(0);
74 }
75
76 int SDL_SemPost(SDL_sem *sem)
77 {
78 SDL_SetError("Semaphores not supported on WinCE");
79 return(-1);
80 }
81
82 #else
83
84 struct SDL_semaphore {
85 HANDLE id;
86 Uint32 volatile count;
87 };
88
89
90 /* Create a semaphore */
91 SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
92 {
93 SDL_sem *sem;
94
95 /* Allocate sem memory */
96 sem = (SDL_sem *)malloc(sizeof(*sem));
97 if ( sem ) {
98 /* Create the semaphore, with max value 32K */
99 sem->id = CreateSemaphore(NULL, initial_value, 32*1024, NULL);
100 sem->count = initial_value;
101 if ( ! sem->id ) {
102 SDL_SetError("Couldn't create semaphore");
103 free(sem);
104 sem = NULL;
105 }
106 } else {
107 SDL_OutOfMemory();
108 }
109 return(sem);
110 }
111
112 /* Free the semaphore */
113 void SDL_DestroySemaphore(SDL_sem *sem)
114 {
115 if ( sem ) {
116 if ( sem->id ) {
117 CloseHandle(sem->id);
118 sem->id = 0;
119 }
120 free(sem);
121 }
122 }
123
124 int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
125 {
126 int retval;
127 DWORD dwMilliseconds;
128
129 if ( ! sem ) {
130 SDL_SetError("Passed a NULL sem");
131 return -1;
132 }
133
134 if ( timeout == SDL_MUTEX_MAXWAIT ) {
135 dwMilliseconds = INFINITE;
136 } else {
137 dwMilliseconds = (DWORD)timeout;
138 }
139 switch (WaitForSingleObject(sem->id, dwMilliseconds)) {
140 case WAIT_OBJECT_0:
141 --sem->count;
142 retval = 0;
143 break;
144 case WAIT_TIMEOUT:
145 retval = SDL_MUTEX_TIMEDOUT;
146 break;
147 default:
148 SDL_SetError("WaitForSingleObject() failed");
149 retval = -1;
150 break;
151 }
152 return retval;
153 }
154
155 int SDL_SemTryWait(SDL_sem *sem)
156 {
157 return SDL_SemWaitTimeout(sem, 0);
158 }
159
160 int SDL_SemWait(SDL_sem *sem)
161 {
162 return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
163 }
164
165 /* Returns the current count of the semaphore */
166 Uint32 SDL_SemValue(SDL_sem *sem)
167 {
168 if ( ! sem ) {
169 SDL_SetError("Passed a NULL sem");
170 return 0;
171 }
172 return sem->count;
173 }
174
175 int SDL_SemPost(SDL_sem *sem)
176 {
177 if ( ! sem ) {
178 SDL_SetError("Passed a NULL sem");
179 return -1;
180 }
181 /* Increase the counter in the first place, because
182 * after a successful release the semaphore may
183 * immediately get destroyed by another thread which
184 * is waiting for this semaphore.
185 */
186 ++sem->count;
187 if ( ReleaseSemaphore(sem->id, 1, NULL) == FALSE ) {
188 --sem->count; /* restore */
189 SDL_SetError("ReleaseSemaphore() failed");
190 return -1;
191 }
192 return 0;
193 }
194
195 #endif /* _WIN32_WCE */