Mercurial > sdl-ios-xcode
comparison src/thread/win32/win_ce_semaphore.c @ 1668:4da1ee79c9af SDL-1.3
more tweaking indent options
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Mon, 29 May 2006 04:04:35 +0000 |
parents | 782fd950bd46 |
children |
comparison
equal
deleted
inserted
replaced
1667:1fddae038bc8 | 1668:4da1ee79c9af |
---|---|
31 #define WIN32_LEAN_AND_MEAN | 31 #define WIN32_LEAN_AND_MEAN |
32 #include <windows.h> | 32 #include <windows.h> |
33 | 33 |
34 #include "win_ce_semaphore.h" | 34 #include "win_ce_semaphore.h" |
35 | 35 |
36 static SYNCHHANDLE CleanUp (SYNCHHANDLE hSynch, DWORD Flags); | 36 static SYNCHHANDLE CleanUp(SYNCHHANDLE hSynch, DWORD Flags); |
37 | 37 |
38 SYNCHHANDLE | 38 SYNCHHANDLE |
39 CreateSemaphoreCE (LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, /* pointer to security attributes */ | 39 CreateSemaphoreCE(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, /* pointer to security attributes */ |
40 LONG lInitialCount, /* initial count */ | 40 LONG lInitialCount, /* initial count */ |
41 LONG lMaximumCount, /* maximum count */ | 41 LONG lMaximumCount, /* maximum count */ |
42 LPCTSTR lpName) | 42 LPCTSTR lpName) |
43 /* Semaphore for use with Windows CE that does not support them directly. | 43 /* Semaphore for use with Windows CE that does not support them directly. |
44 Requires a counter, a mutex to protect the counter, and an | 44 Requires a counter, a mutex to protect the counter, and an |
45 autoreset event. | 45 autoreset event. |
46 | 46 |
47 Here are the rules that must always hold between the autoreset event | 47 Here are the rules that must always hold between the autoreset event |
60 | 60 |
61 __try { | 61 __try { |
62 if (lInitialCount > lMaximumCount || lMaximumCount < 0 | 62 if (lInitialCount > lMaximumCount || lMaximumCount < 0 |
63 || lInitialCount < 0) { | 63 || lInitialCount < 0) { |
64 /* Bad parameters */ | 64 /* Bad parameters */ |
65 SetLastError (SYNCH_ERROR); | 65 SetLastError(SYNCH_ERROR); |
66 __leave; | 66 __leave; |
67 } | 67 } |
68 | 68 |
69 hSynch = | 69 hSynch = |
70 HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, | 70 HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, SYNCH_HANDLE_SIZE); |
71 SYNCH_HANDLE_SIZE); | |
72 if (hSynch == NULL) | 71 if (hSynch == NULL) |
73 __leave; | 72 __leave; |
74 | 73 |
75 hSynch->MaxCount = lMaximumCount; | 74 hSynch->MaxCount = lMaximumCount; |
76 hSynch->CurCount = lInitialCount; | 75 hSynch->CurCount = lInitialCount; |
77 hSynch->lpName = lpName; | 76 hSynch->lpName = lpName; |
78 | 77 |
79 hSynch->hMutex = CreateMutex (lpSemaphoreAttributes, FALSE, NULL); | 78 hSynch->hMutex = CreateMutex(lpSemaphoreAttributes, FALSE, NULL); |
80 | 79 |
81 WaitForSingleObject (hSynch->hMutex, INFINITE); | 80 WaitForSingleObject(hSynch->hMutex, INFINITE); |
82 /* Create the event. It is initially signaled if and only if the | 81 /* Create the event. It is initially signaled if and only if the |
83 initial count is > 0 */ | 82 initial count is > 0 */ |
84 hSynch->hEvent = CreateEvent (lpSemaphoreAttributes, FALSE, | 83 hSynch->hEvent = CreateEvent(lpSemaphoreAttributes, FALSE, |
85 lInitialCount > 0, NULL); | 84 lInitialCount > 0, NULL); |
86 ReleaseMutex (hSynch->hMutex); | 85 ReleaseMutex(hSynch->hMutex); |
87 hSynch->hSemph = NULL; | 86 hSynch->hSemph = NULL; |
88 } | 87 } |
89 __finally { | 88 __finally { |
90 /* Return with the handle, or, if there was any error, return | 89 /* Return with the handle, or, if there was any error, return |
91 a null after closing any open handles and freeing any allocated memory. */ | 90 a null after closing any open handles and freeing any allocated memory. */ |
92 result = | 91 result = |
93 CleanUp (hSynch, | 92 CleanUp(hSynch, 6 /* An event and a mutex, but no semaphore. */ ); |
94 6 /* An event and a mutex, but no semaphore. */ ); | |
95 } | 93 } |
96 | 94 |
97 return result; | 95 return result; |
98 } | 96 } |
99 | 97 |
100 BOOL | 98 BOOL |
101 ReleaseSemaphoreCE (SYNCHHANDLE hSemCE, LONG cReleaseCount, | 99 ReleaseSemaphoreCE(SYNCHHANDLE hSemCE, LONG cReleaseCount, |
102 LPLONG lpPreviousCount) | 100 LPLONG lpPreviousCount) |
103 /* Windows CE equivalent to ReleaseSemaphore. */ | 101 /* Windows CE equivalent to ReleaseSemaphore. */ |
104 { | 102 { |
105 BOOL Result = TRUE; | 103 BOOL Result = TRUE; |
106 | 104 |
107 /* Gain access to the object to assure that the release count | 105 /* Gain access to the object to assure that the release count |
108 would not cause the total count to exceed the maximum. */ | 106 would not cause the total count to exceed the maximum. */ |
109 | 107 |
110 __try { | 108 __try { |
111 WaitForSingleObject (hSemCE->hMutex, INFINITE); | 109 WaitForSingleObject(hSemCE->hMutex, INFINITE); |
112 /* reply only if asked to */ | 110 /* reply only if asked to */ |
113 if (lpPreviousCount != NULL) | 111 if (lpPreviousCount != NULL) |
114 *lpPreviousCount = hSemCE->CurCount; | 112 *lpPreviousCount = hSemCE->CurCount; |
115 if (hSemCE->CurCount + cReleaseCount > hSemCE->MaxCount | 113 if (hSemCE->CurCount + cReleaseCount > hSemCE->MaxCount |
116 || cReleaseCount <= 0) { | 114 || cReleaseCount <= 0) { |
117 SetLastError (SYNCH_ERROR); | 115 SetLastError(SYNCH_ERROR); |
118 Result = FALSE; | 116 Result = FALSE; |
119 __leave; | 117 __leave; |
120 } | 118 } |
121 hSemCE->CurCount += cReleaseCount; | 119 hSemCE->CurCount += cReleaseCount; |
122 | 120 |
123 /* Set the autoreset event, releasing exactly one waiting thread, now or | 121 /* Set the autoreset event, releasing exactly one waiting thread, now or |
124 in the future. */ | 122 in the future. */ |
125 | 123 |
126 SetEvent (hSemCE->hEvent); | 124 SetEvent(hSemCE->hEvent); |
127 } | 125 } |
128 __finally { | 126 __finally { |
129 ReleaseMutex (hSemCE->hMutex); | 127 ReleaseMutex(hSemCE->hMutex); |
130 } | 128 } |
131 | 129 |
132 return Result; | 130 return Result; |
133 } | 131 } |
134 | 132 |
135 DWORD | 133 DWORD |
136 WaitForSemaphoreCE (SYNCHHANDLE hSemCE, DWORD dwMilliseconds) | 134 WaitForSemaphoreCE(SYNCHHANDLE hSemCE, DWORD dwMilliseconds) |
137 /* Windows CE semaphore equivalent of WaitForSingleObject. */ | 135 /* Windows CE semaphore equivalent of WaitForSingleObject. */ |
138 { | 136 { |
139 DWORD WaitResult; | 137 DWORD WaitResult; |
140 | 138 |
141 WaitResult = WaitForSingleObject (hSemCE->hMutex, dwMilliseconds); | 139 WaitResult = WaitForSingleObject(hSemCE->hMutex, dwMilliseconds); |
142 if (WaitResult != WAIT_OBJECT_0 && WaitResult != WAIT_ABANDONED_0) | 140 if (WaitResult != WAIT_OBJECT_0 && WaitResult != WAIT_ABANDONED_0) |
143 return WaitResult; | 141 return WaitResult; |
144 while (hSemCE->CurCount <= 0) { | 142 while (hSemCE->CurCount <= 0) { |
145 | 143 |
146 /* The count is 0, and the thread must wait on the event (which, by | 144 /* The count is 0, and the thread must wait on the event (which, by |
147 the rules, is currently reset) for semaphore resources to become | 145 the rules, is currently reset) for semaphore resources to become |
148 available. First, of course, the mutex must be released so that another | 146 available. First, of course, the mutex must be released so that another |
149 thread will be capable of setting the event. */ | 147 thread will be capable of setting the event. */ |
150 | 148 |
151 ReleaseMutex (hSemCE->hMutex); | 149 ReleaseMutex(hSemCE->hMutex); |
152 | 150 |
153 /* Wait for the event to be signaled, indicating a semaphore state change. | 151 /* Wait for the event to be signaled, indicating a semaphore state change. |
154 The event is autoreset and signaled with a SetEvent (not PulseEvent) | 152 The event is autoreset and signaled with a SetEvent (not PulseEvent) |
155 so exactly one waiting thread (whether or not there is currently | 153 so exactly one waiting thread (whether or not there is currently |
156 a waiting thread) is released as a result of the SetEvent. */ | 154 a waiting thread) is released as a result of the SetEvent. */ |
157 | 155 |
158 WaitResult = WaitForSingleObject (hSemCE->hEvent, dwMilliseconds); | 156 WaitResult = WaitForSingleObject(hSemCE->hEvent, dwMilliseconds); |
159 if (WaitResult != WAIT_OBJECT_0) | 157 if (WaitResult != WAIT_OBJECT_0) |
160 return WaitResult; | 158 return WaitResult; |
161 | 159 |
162 /* This is where the properties of setting of an autoreset event is critical | 160 /* This is where the properties of setting of an autoreset event is critical |
163 to assure that, even if the semaphore state changes between the | 161 to assure that, even if the semaphore state changes between the |
166 will be released. | 164 will be released. |
167 Pulsing a manual reset event would appear to work, but it would have | 165 Pulsing a manual reset event would appear to work, but it would have |
168 a defect which could appear if the semaphore state changed between | 166 a defect which could appear if the semaphore state changed between |
169 the two waits. */ | 167 the two waits. */ |
170 | 168 |
171 WaitResult = WaitForSingleObject (hSemCE->hMutex, dwMilliseconds); | 169 WaitResult = WaitForSingleObject(hSemCE->hMutex, dwMilliseconds); |
172 if (WaitResult != WAIT_OBJECT_0 && WaitResult != WAIT_ABANDONED_0) | 170 if (WaitResult != WAIT_OBJECT_0 && WaitResult != WAIT_ABANDONED_0) |
173 return WaitResult; | 171 return WaitResult; |
174 | 172 |
175 } | 173 } |
176 /* The count is not zero and this thread owns the mutex. */ | 174 /* The count is not zero and this thread owns the mutex. */ |
179 /* The event is now unsignaled, BUT, the semaphore count may not be | 177 /* The event is now unsignaled, BUT, the semaphore count may not be |
180 zero, in which case the event should be signaled again | 178 zero, in which case the event should be signaled again |
181 before releasing the mutex. */ | 179 before releasing the mutex. */ |
182 | 180 |
183 if (hSemCE->CurCount > 0) | 181 if (hSemCE->CurCount > 0) |
184 SetEvent (hSemCE->hEvent); | 182 SetEvent(hSemCE->hEvent); |
185 ReleaseMutex (hSemCE->hMutex); | 183 ReleaseMutex(hSemCE->hMutex); |
186 return WaitResult; | 184 return WaitResult; |
187 } | 185 } |
188 | 186 |
189 BOOL | 187 BOOL |
190 CloseSynchHandle (SYNCHHANDLE hSynch) | 188 CloseSynchHandle(SYNCHHANDLE hSynch) |
191 /* Close a synchronization handle. | 189 /* Close a synchronization handle. |
192 Improvement: Test for a valid handle before dereferencing the handle. */ | 190 Improvement: Test for a valid handle before dereferencing the handle. */ |
193 { | 191 { |
194 BOOL Result = TRUE; | 192 BOOL Result = TRUE; |
195 if (hSynch->hEvent != NULL) | 193 if (hSynch->hEvent != NULL) |
196 Result = Result && CloseHandle (hSynch->hEvent); | 194 Result = Result && CloseHandle(hSynch->hEvent); |
197 if (hSynch->hMutex != NULL) | 195 if (hSynch->hMutex != NULL) |
198 Result = Result && CloseHandle (hSynch->hMutex); | 196 Result = Result && CloseHandle(hSynch->hMutex); |
199 if (hSynch->hSemph != NULL) | 197 if (hSynch->hSemph != NULL) |
200 Result = Result && CloseHandle (hSynch->hSemph); | 198 Result = Result && CloseHandle(hSynch->hSemph); |
201 HeapFree (GetProcessHeap (), 0, hSynch); | 199 HeapFree(GetProcessHeap(), 0, hSynch); |
202 return (Result); | 200 return (Result); |
203 } | 201 } |
204 | 202 |
205 static SYNCHHANDLE | 203 static SYNCHHANDLE |
206 CleanUp (SYNCHHANDLE hSynch, DWORD Flags) | 204 CleanUp(SYNCHHANDLE hSynch, DWORD Flags) |
207 { /* Prepare to return from a create of a synchronization handle. | 205 { /* Prepare to return from a create of a synchronization handle. |
208 If there was any failure, free any allocated resources. | 206 If there was any failure, free any allocated resources. |
209 "Flags" indicates which Win32 objects are required in the | 207 "Flags" indicates which Win32 objects are required in the |
210 synchronization handle. */ | 208 synchronization handle. */ |
211 | 209 |
218 if ((Flags & 2) == 1 && (hSynch->hMutex == NULL)) | 216 if ((Flags & 2) == 1 && (hSynch->hMutex == NULL)) |
219 ok = FALSE; | 217 ok = FALSE; |
220 if ((Flags & 1) == 1 && (hSynch->hEvent == NULL)) | 218 if ((Flags & 1) == 1 && (hSynch->hEvent == NULL)) |
221 ok = FALSE; | 219 ok = FALSE; |
222 if (!ok) { | 220 if (!ok) { |
223 CloseSynchHandle (hSynch); | 221 CloseSynchHandle(hSynch); |
224 return NULL; | 222 return NULL; |
225 } | 223 } |
226 /* Everything worked */ | 224 /* Everything worked */ |
227 return hSynch; | 225 return hSynch; |
228 } | 226 } |