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 }