annotate src/thread/win32/win_ce_semaphore.c @ 878:c7ca0f3cbca2

Argh...
author Sam Lantinga <slouken@libsdl.org>
date Thu, 08 Apr 2004 21:06:10 +0000
parents 13ee9f4834ea
children 86d0d01290ea
rev   line source
36
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
1 /* win_ce_semaphore.c
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
2
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
3 Copyright (c) 1998, Johnson M. Hart
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
4 (with corrections 2001 by Rainer Loritz)
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
5 Permission is granted for any and all use providing that this
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
6 copyright is properly acknowledged.
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
7 There are no assurances of suitability for any use whatsoever.
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
8
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
9 WINDOWS CE: There is a collection of Windows CE functions to simulate
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
10 semaphores using only a mutex and an event. As Windows CE events cannot
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
11 be named, these simulated semaphores cannot be named either.
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
12
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
13 Implementation notes:
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
14 1. All required internal data structures are allocated on the process's heap.
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
15 2. Where appropriate, a new error code is returned (see the header
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
16 file), or, if the error is a Win32 error, that code is unchanged.
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
17 3. Notice the new handle type "SYNCHHANDLE" that has handles, counters,
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
18 and other information. This structure will grow as new objects are added
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
19 to this set; some members are specific to only one or two of the objects.
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
20 4. Mutexes are used for critical sections. These could be replaced with
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
21 CRITICAL_SECTION objects but then this would give up the time out
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
22 capability.
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
23 5. The implementation shows several interesting aspects of synchronization, some
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
24 of which are specific to Win32 and some of which are general. These are pointed
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
25 out in the comments as appropriate.
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
26 6. The wait function emulates WaitForSingleObject only. An emulation of
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
27 WaitForMultipleObjects is much harder to implement outside the kernel,
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
28 and it is not clear how to handle a mixture of WCE semaphores and normal
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
29 events and mutexes. */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
30
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
31 #include <windows.h>
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
32 #include "win_ce_semaphore.h"
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
33
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
34 static SYNCHHANDLE CleanUp (SYNCHHANDLE hSynch, DWORD Flags);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
35
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
36 SYNCHHANDLE CreateSemaphoreCE (
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
37
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
38 LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, /* pointer to security attributes */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
39 LONG lInitialCount, /* initial count */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
40 LONG lMaximumCount, /* maximum count */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
41 LPCTSTR lpName )
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
42
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
43 /* Semaphore for use with Windows CE that does not support them directly.
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
44 Requires a counter, a mutex to protect the counter, and an
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
45 autoreset event.
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
46
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
47 Here are the rules that must always hold between the autoreset event
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
48 and the mutex (any violation of these rules by the CE semaphore functions
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
49 will, in all likelihood, result in a defect):
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
50 1. No thread can set, pulse, or reset the event,
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
51 nor can it access any part of the SYNCHHANDLE structure,
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
52 without first gaining ownership of the mutex.
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
53 BUT, a thread can wait on the event without owning the mutex
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
54 (this is clearly necessary or else the event could never be set).
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
55 2. The event is in a signaled state if and only if the current semaphore
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
56 count ("CurCount") is greater than zero.
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
57 3. The semaphore count is always >= 0 and <= the maximum count */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
58
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
59 {
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
60 SYNCHHANDLE hSynch = NULL, result = NULL;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
61
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
62 __try
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
63 {
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
64 if (lInitialCount > lMaximumCount || lMaximumCount < 0 || lInitialCount < 0)
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
65 {
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
66 /* Bad parameters */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
67 SetLastError (SYNCH_ERROR);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
68 __leave;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
69 }
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
70
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
71 hSynch = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, SYNCH_HANDLE_SIZE);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
72 if (hSynch == NULL) __leave;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
73
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
74 hSynch->MaxCount = lMaximumCount;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
75 hSynch->CurCount = lInitialCount;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
76 hSynch->lpName = lpName;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
77
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
78 hSynch->hMutex = CreateMutex (lpSemaphoreAttributes, FALSE, NULL);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
79
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
80 WaitForSingleObject (hSynch->hMutex, INFINITE);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
81 /* Create the event. It is initially signaled if and only if the
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
82 initial count is > 0 */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
83 hSynch->hEvent = CreateEvent (lpSemaphoreAttributes, FALSE,
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
84 lInitialCount > 0, NULL);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
85 ReleaseMutex (hSynch->hMutex);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
86 hSynch->hSemph = NULL;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
87 }
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
88 __finally
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
89 {
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
90 /* Return with the handle, or, if there was any error, return
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
91 a null after closing any open handles and freeing any allocated memory. */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
92 result=CleanUp(hSynch, 6 /* An event and a mutex, but no semaphore. */);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
93 }
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
94
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
95 return result;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
96 }
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
97
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
98 BOOL ReleaseSemaphoreCE (SYNCHHANDLE hSemCE, LONG cReleaseCount, LPLONG lpPreviousCount)
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
99 /* Windows CE equivalent to ReleaseSemaphore. */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
100 {
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
101 BOOL Result = TRUE;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
102
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
103 /* Gain access to the object to assure that the release count
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
104 would not cause the total count to exceed the maximum. */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
105
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
106 __try
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
107 {
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
108 WaitForSingleObject (hSemCE->hMutex, INFINITE);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
109 /* reply only if asked to */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
110 if (lpPreviousCount!=NULL)
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
111 *lpPreviousCount = hSemCE->CurCount;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
112 if (hSemCE->CurCount + cReleaseCount > hSemCE->MaxCount || cReleaseCount <= 0)
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
113 {
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
114 SetLastError (SYNCH_ERROR);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
115 Result = FALSE;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
116 __leave;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
117 }
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
118 hSemCE->CurCount += cReleaseCount;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
119
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
120 /* Set the autoreset event, releasing exactly one waiting thread, now or
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
121 in the future. */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
122
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
123 SetEvent (hSemCE->hEvent);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
124 }
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
125 __finally
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
126 {
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
127 ReleaseMutex (hSemCE->hMutex);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
128 }
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
129
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
130 return Result;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
131 }
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
132
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
133 DWORD WaitForSemaphoreCE (SYNCHHANDLE hSemCE, DWORD dwMilliseconds)
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
134 /* Windows CE semaphore equivalent of WaitForSingleObject. */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
135 {
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
136 DWORD WaitResult;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
137
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
138 WaitResult = WaitForSingleObject (hSemCE->hMutex, dwMilliseconds);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
139 if (WaitResult != WAIT_OBJECT_0 && WaitResult != WAIT_ABANDONED_0) return WaitResult;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
140 while (hSemCE->CurCount <= 0)
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
141 {
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
142
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
143 /* The count is 0, and the thread must wait on the event (which, by
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
144 the rules, is currently reset) for semaphore resources to become
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
145 available. First, of course, the mutex must be released so that another
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
146 thread will be capable of setting the event. */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
147
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
148 ReleaseMutex (hSemCE->hMutex);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
149
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
150 /* Wait for the event to be signaled, indicating a semaphore state change.
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
151 The event is autoreset and signaled with a SetEvent (not PulseEvent)
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
152 so exactly one waiting thread (whether or not there is currently
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
153 a waiting thread) is released as a result of the SetEvent. */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
154
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
155 WaitResult = WaitForSingleObject (hSemCE->hEvent, dwMilliseconds);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
156 if (WaitResult != WAIT_OBJECT_0) return WaitResult;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
157
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
158 /* This is where the properties of setting of an autoreset event is critical
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
159 to assure that, even if the semaphore state changes between the
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
160 preceding Wait and the next, and even if NO threads are waiting
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
161 on the event at the time of the SetEvent, at least one thread
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
162 will be released.
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
163 Pulsing a manual reset event would appear to work, but it would have
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
164 a defect which could appear if the semaphore state changed between
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
165 the two waits. */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
166
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
167 WaitResult = WaitForSingleObject (hSemCE->hMutex, dwMilliseconds);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
168 if (WaitResult != WAIT_OBJECT_0 && WaitResult != WAIT_ABANDONED_0) return WaitResult;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
169
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
170 }
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
171 /* The count is not zero and this thread owns the mutex. */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
172
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
173 hSemCE->CurCount--;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
174 /* The event is now unsignaled, BUT, the semaphore count may not be
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
175 zero, in which case the event should be signaled again
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
176 before releasing the mutex. */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
177
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
178 if (hSemCE->CurCount > 0) SetEvent (hSemCE->hEvent);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
179 ReleaseMutex (hSemCE->hMutex);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
180 return WaitResult;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
181 }
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
182
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
183 BOOL CloseSynchHandle (SYNCHHANDLE hSynch)
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
184 /* Close a synchronization handle.
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
185 Improvement: Test for a valid handle before dereferencing the handle. */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
186 {
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
187 BOOL Result = TRUE;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
188 if (hSynch->hEvent != NULL) Result = Result && CloseHandle (hSynch->hEvent);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
189 if (hSynch->hMutex != NULL) Result = Result && CloseHandle (hSynch->hMutex);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
190 if (hSynch->hSemph != NULL) Result = Result && CloseHandle (hSynch->hSemph);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
191 HeapFree (GetProcessHeap (), 0, hSynch);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
192 return (Result);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
193 }
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
194
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
195 static SYNCHHANDLE CleanUp (SYNCHHANDLE hSynch, DWORD Flags)
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
196 { /* Prepare to return from a create of a synchronization handle.
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
197 If there was any failure, free any allocated resources.
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
198 "Flags" indicates which Win32 objects are required in the
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
199 synchronization handle. */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
200
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
201 BOOL ok = TRUE;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
202
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
203 if (hSynch == NULL) return NULL;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
204 if (Flags & 4 == 1 && hSynch->hEvent == NULL) ok = FALSE;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
205 if (Flags & 2 == 1 && hSynch->hMutex == NULL) ok = FALSE;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
206 if (Flags & 1 == 1 && hSynch->hEvent == NULL) ok = FALSE;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
207 if (!ok)
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
208 {
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
209 CloseSynchHandle (hSynch);
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
210 return NULL;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
211 }
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
212 /* Everything worked */
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
213 return hSynch;
13ee9f4834ea Windows CE patches contributed by Rainer Loritz
Sam Lantinga <slouken@lokigames.com>
parents:
diff changeset
214 }