SDL-1.2.14
[sdl_omap.git] / src / thread / win32 / SDL_syssem.c
CommitLineData
e14743d1 1/*
2 SDL - Simple DirectMedia Layer
3 Copyright (C) 1997-2009 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
35struct SDL_semaphore {
36#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
37 SYNCHHANDLE id;
38#else
39 HANDLE id;
40#endif
41 Uint32 volatile count;
42};
43
44
45/* Create a semaphore */
46SDL_sem *SDL_CreateSemaphore(Uint32 initial_value)
47{
48 SDL_sem *sem;
49
50 /* Allocate sem memory */
51 sem = (SDL_sem *)SDL_malloc(sizeof(*sem));
52 if ( sem ) {
53 /* Create the semaphore, with max value 32K */
54#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
55 sem->id = CreateSemaphoreCE(NULL, initial_value, 32*1024, NULL);
56#else
57 sem->id = CreateSemaphore(NULL, initial_value, 32*1024, NULL);
58#endif
59 sem->count = initial_value;
60 if ( ! sem->id ) {
61 SDL_SetError("Couldn't create semaphore");
62 SDL_free(sem);
63 sem = NULL;
64 }
65 } else {
66 SDL_OutOfMemory();
67 }
68 return(sem);
69}
70
71/* Free the semaphore */
72void SDL_DestroySemaphore(SDL_sem *sem)
73{
74 if ( sem ) {
75 if ( sem->id ) {
76#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
77 CloseSynchHandle(sem->id);
78#else
79 CloseHandle(sem->id);
80#endif
81 sem->id = 0;
82 }
83 SDL_free(sem);
84 }
85}
86
87int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout)
88{
89 int retval;
90 DWORD dwMilliseconds;
91
92 if ( ! sem ) {
93 SDL_SetError("Passed a NULL sem");
94 return -1;
95 }
96
97 if ( timeout == SDL_MUTEX_MAXWAIT ) {
98 dwMilliseconds = INFINITE;
99 } else {
100 dwMilliseconds = (DWORD)timeout;
101 }
102#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
103 switch (WaitForSemaphoreCE(sem->id, dwMilliseconds)) {
104#else
105 switch (WaitForSingleObject(sem->id, dwMilliseconds)) {
106#endif
107 case WAIT_OBJECT_0:
108 InterlockedDecrement(&sem->count);
109 retval = 0;
110 break;
111 case WAIT_TIMEOUT:
112 retval = SDL_MUTEX_TIMEDOUT;
113 break;
114 default:
115 SDL_SetError("WaitForSingleObject() failed");
116 retval = -1;
117 break;
118 }
119 return retval;
120}
121
122int SDL_SemTryWait(SDL_sem *sem)
123{
124 return SDL_SemWaitTimeout(sem, 0);
125}
126
127int SDL_SemWait(SDL_sem *sem)
128{
129 return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
130}
131
132/* Returns the current count of the semaphore */
133Uint32 SDL_SemValue(SDL_sem *sem)
134{
135 if ( ! sem ) {
136 SDL_SetError("Passed a NULL sem");
137 return 0;
138 }
139 return sem->count;
140}
141
142int SDL_SemPost(SDL_sem *sem)
143{
144 if ( ! sem ) {
145 SDL_SetError("Passed a NULL sem");
146 return -1;
147 }
148 /* Increase the counter in the first place, because
149 * after a successful release the semaphore may
150 * immediately get destroyed by another thread which
151 * is waiting for this semaphore.
152 */
153 InterlockedIncrement(&sem->count);
154#if defined(_WIN32_WCE) && (_WIN32_WCE < 300)
155 if ( ReleaseSemaphoreCE(sem->id, 1, NULL) == FALSE ) {
156#else
157 if ( ReleaseSemaphore(sem->id, 1, NULL) == FALSE ) {
158#endif
159 InterlockedDecrement(&sem->count); /* restore */
160 SDL_SetError("ReleaseSemaphore() failed");
161 return -1;
162 }
163 return 0;
164}