diff options
Diffstat (limited to 'apps/plugins/sdl/src/thread/win32')
-rw-r--r-- | apps/plugins/sdl/src/thread/win32/SDL_sysmutex.c | 95 | ||||
-rw-r--r-- | apps/plugins/sdl/src/thread/win32/SDL_syssem.c | 164 | ||||
-rw-r--r-- | apps/plugins/sdl/src/thread/win32/SDL_systhread.c | 162 | ||||
-rw-r--r-- | apps/plugins/sdl/src/thread/win32/SDL_systhread_c.h | 28 | ||||
-rw-r--r-- | apps/plugins/sdl/src/thread/win32/win_ce_semaphore.c | 216 | ||||
-rw-r--r-- | apps/plugins/sdl/src/thread/win32/win_ce_semaphore.h | 22 |
6 files changed, 0 insertions, 687 deletions
diff --git a/apps/plugins/sdl/src/thread/win32/SDL_sysmutex.c b/apps/plugins/sdl/src/thread/win32/SDL_sysmutex.c deleted file mode 100644 index 1d7805c062..0000000000 --- a/apps/plugins/sdl/src/thread/win32/SDL_sysmutex.c +++ /dev/null | |||
@@ -1,95 +0,0 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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 | /* Mutex functions using the Win32 API */ | ||
25 | |||
26 | #define WIN32_LEAN_AND_MEAN | ||
27 | #include <windows.h> | ||
28 | |||
29 | #include "SDL_mutex.h" | ||
30 | |||
31 | |||
32 | struct SDL_mutex { | ||
33 | HANDLE id; | ||
34 | }; | ||
35 | |||
36 | /* Create a mutex */ | ||
37 | SDL_mutex *SDL_CreateMutex(void) | ||
38 | { | ||
39 | SDL_mutex *mutex; | ||
40 | |||
41 | /* Allocate mutex memory */ | ||
42 | mutex = (SDL_mutex *)SDL_malloc(sizeof(*mutex)); | ||
43 | if ( mutex ) { | ||
44 | /* Create the mutex, with initial value signaled */ | ||
45 | mutex->id = CreateMutex(NULL, FALSE, NULL); | ||
46 | if ( ! mutex->id ) { | ||
47 | SDL_SetError("Couldn't create mutex"); | ||
48 | SDL_free(mutex); | ||
49 | mutex = NULL; | ||
50 | } | ||
51 | } else { | ||
52 | SDL_OutOfMemory(); | ||
53 | } | ||
54 | return(mutex); | ||
55 | } | ||
56 | |||
57 | /* Free the mutex */ | ||
58 | void SDL_DestroyMutex(SDL_mutex *mutex) | ||
59 | { | ||
60 | if ( mutex ) { | ||
61 | if ( mutex->id ) { | ||
62 | CloseHandle(mutex->id); | ||
63 | mutex->id = 0; | ||
64 | } | ||
65 | SDL_free(mutex); | ||
66 | } | ||
67 | } | ||
68 | |||
69 | /* Lock the mutex */ | ||
70 | int SDL_mutexP(SDL_mutex *mutex) | ||
71 | { | ||
72 | if ( mutex == NULL ) { | ||
73 | SDL_SetError("Passed a NULL mutex"); | ||
74 | return -1; | ||
75 | } | ||
76 | if ( WaitForSingleObject(mutex->id, INFINITE) == WAIT_FAILED ) { | ||
77 | SDL_SetError("Couldn't wait on mutex"); | ||
78 | return -1; | ||
79 | } | ||
80 | return(0); | ||
81 | } | ||
82 | |||
83 | /* Unlock the mutex */ | ||
84 | int SDL_mutexV(SDL_mutex *mutex) | ||
85 | { | ||
86 | if ( mutex == NULL ) { | ||
87 | SDL_SetError("Passed a NULL mutex"); | ||
88 | return -1; | ||
89 | } | ||
90 | if ( ReleaseMutex(mutex->id) == FALSE ) { | ||
91 | SDL_SetError("Couldn't release mutex"); | ||
92 | return -1; | ||
93 | } | ||
94 | return(0); | ||
95 | } | ||
diff --git a/apps/plugins/sdl/src/thread/win32/SDL_syssem.c b/apps/plugins/sdl/src/thread/win32/SDL_syssem.c deleted file mode 100644 index 261d24cbfe..0000000000 --- a/apps/plugins/sdl/src/thread/win32/SDL_syssem.c +++ /dev/null | |||
@@ -1,164 +0,0 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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 | |||
35 | struct SDL_semaphore { | ||
36 | #if defined(_WIN32_WCE) && (_WIN32_WCE < 300) | ||
37 | SYNCHHANDLE id; | ||
38 | #else | ||
39 | HANDLE id; | ||
40 | #endif | ||
41 | volatile LONG count; | ||
42 | }; | ||
43 | |||
44 | |||
45 | /* Create a semaphore */ | ||
46 | SDL_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 = (LONG) 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 */ | ||
72 | void 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 | |||
87 | int 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 | |||
122 | int SDL_SemTryWait(SDL_sem *sem) | ||
123 | { | ||
124 | return SDL_SemWaitTimeout(sem, 0); | ||
125 | } | ||
126 | |||
127 | int SDL_SemWait(SDL_sem *sem) | ||
128 | { | ||
129 | return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT); | ||
130 | } | ||
131 | |||
132 | /* Returns the current count of the semaphore */ | ||
133 | Uint32 SDL_SemValue(SDL_sem *sem) | ||
134 | { | ||
135 | if ( ! sem ) { | ||
136 | SDL_SetError("Passed a NULL sem"); | ||
137 | return 0; | ||
138 | } | ||
139 | return (Uint32) sem->count; | ||
140 | } | ||
141 | |||
142 | int 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 | } | ||
diff --git a/apps/plugins/sdl/src/thread/win32/SDL_systhread.c b/apps/plugins/sdl/src/thread/win32/SDL_systhread.c deleted file mode 100644 index 55cb88a58c..0000000000 --- a/apps/plugins/sdl/src/thread/win32/SDL_systhread.c +++ /dev/null | |||
@@ -1,162 +0,0 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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 | /* Win32 thread management routines for SDL */ | ||
25 | |||
26 | #define WIN32_LEAN_AND_MEAN | ||
27 | #include <windows.h> | ||
28 | |||
29 | #include "SDL_thread.h" | ||
30 | #include "../SDL_thread_c.h" | ||
31 | #include "../SDL_systhread.h" | ||
32 | |||
33 | #ifndef SDL_PASSED_BEGINTHREAD_ENDTHREAD | ||
34 | #ifndef _WIN32_WCE | ||
35 | /* We'll use the C library from this DLL */ | ||
36 | #include <process.h> | ||
37 | #endif | ||
38 | |||
39 | #if defined(__WATCOMC__) | ||
40 | /* This is for Watcom targets except OS2 */ | ||
41 | #if __WATCOMC__ < 1240 | ||
42 | #define __watcall | ||
43 | #endif | ||
44 | typedef unsigned long (__watcall *pfnSDL_CurrentBeginThread) (void *, unsigned, | ||
45 | unsigned (__stdcall *func)(void *), void *arg, | ||
46 | unsigned, unsigned *threadID); | ||
47 | typedef void (__watcall *pfnSDL_CurrentEndThread)(unsigned code); | ||
48 | #elif (defined(__MINGW32__) && (__GNUC__ < 4)) | ||
49 | typedef unsigned long (__cdecl *pfnSDL_CurrentBeginThread) (void *, unsigned, | ||
50 | unsigned (__stdcall *func)(void *), void *arg, | ||
51 | unsigned, unsigned *threadID); | ||
52 | typedef void (__cdecl *pfnSDL_CurrentEndThread)(unsigned code); | ||
53 | #else | ||
54 | typedef uintptr_t (__cdecl *pfnSDL_CurrentBeginThread) (void *, unsigned, | ||
55 | unsigned (__stdcall *func)(void *), void *arg, | ||
56 | unsigned, unsigned *threadID); | ||
57 | typedef void (__cdecl *pfnSDL_CurrentEndThread)(unsigned code); | ||
58 | #endif | ||
59 | #endif /* !SDL_PASSED_BEGINTHREAD_ENDTHREAD */ | ||
60 | |||
61 | |||
62 | typedef struct ThreadStartParms | ||
63 | { | ||
64 | void *args; | ||
65 | pfnSDL_CurrentEndThread pfnCurrentEndThread; | ||
66 | } tThreadStartParms, *pThreadStartParms; | ||
67 | |||
68 | static DWORD RunThread(void *data) | ||
69 | { | ||
70 | pThreadStartParms pThreadParms = (pThreadStartParms)data; | ||
71 | pfnSDL_CurrentEndThread pfnCurrentEndThread = NULL; | ||
72 | |||
73 | // Call the thread function! | ||
74 | SDL_RunThread(pThreadParms->args); | ||
75 | |||
76 | // Get the current endthread we have to use! | ||
77 | if (pThreadParms) | ||
78 | { | ||
79 | pfnCurrentEndThread = pThreadParms->pfnCurrentEndThread; | ||
80 | SDL_free(pThreadParms); | ||
81 | } | ||
82 | // Call endthread! | ||
83 | if (pfnCurrentEndThread) | ||
84 | (*pfnCurrentEndThread)(0); | ||
85 | return(0); | ||
86 | } | ||
87 | |||
88 | static DWORD WINAPI RunThreadViaCreateThread(LPVOID data) | ||
89 | { | ||
90 | return RunThread(data); | ||
91 | } | ||
92 | |||
93 | static unsigned __stdcall RunThreadViaBeginThreadEx(void *data) | ||
94 | { | ||
95 | return (unsigned) RunThread(data); | ||
96 | } | ||
97 | |||
98 | #ifdef SDL_PASSED_BEGINTHREAD_ENDTHREAD | ||
99 | int SDL_SYS_CreateThread(SDL_Thread *thread, void *args, pfnSDL_CurrentBeginThread pfnBeginThread, pfnSDL_CurrentEndThread pfnEndThread) | ||
100 | { | ||
101 | #else | ||
102 | int SDL_SYS_CreateThread(SDL_Thread *thread, void *args) | ||
103 | { | ||
104 | #ifdef _WIN32_WCE | ||
105 | pfnSDL_CurrentBeginThread pfnBeginThread = NULL; | ||
106 | pfnSDL_CurrentEndThread pfnEndThread = NULL; | ||
107 | #else | ||
108 | pfnSDL_CurrentBeginThread pfnBeginThread = _beginthreadex; | ||
109 | pfnSDL_CurrentEndThread pfnEndThread = _endthreadex; | ||
110 | #endif | ||
111 | #endif /* SDL_PASSED_BEGINTHREAD_ENDTHREAD */ | ||
112 | pThreadStartParms pThreadParms = (pThreadStartParms)SDL_malloc(sizeof(tThreadStartParms)); | ||
113 | if (!pThreadParms) { | ||
114 | SDL_OutOfMemory(); | ||
115 | return(-1); | ||
116 | } | ||
117 | |||
118 | // Save the function which we will have to call to clear the RTL of calling app! | ||
119 | pThreadParms->pfnCurrentEndThread = pfnEndThread; | ||
120 | // Also save the real parameters we have to pass to thread function | ||
121 | pThreadParms->args = args; | ||
122 | |||
123 | if (pfnBeginThread) { | ||
124 | unsigned threadid = 0; | ||
125 | thread->handle = (SYS_ThreadHandle) | ||
126 | ((size_t) pfnBeginThread(NULL, 0, RunThreadViaBeginThreadEx, | ||
127 | pThreadParms, 0, &threadid)); | ||
128 | } else { | ||
129 | DWORD threadid = 0; | ||
130 | thread->handle = CreateThread(NULL, 0, RunThreadViaCreateThread, pThreadParms, 0, &threadid); | ||
131 | } | ||
132 | if (thread->handle == NULL) { | ||
133 | SDL_SetError("Not enough resources to create thread"); | ||
134 | return(-1); | ||
135 | } | ||
136 | return(0); | ||
137 | } | ||
138 | |||
139 | void SDL_SYS_SetupThread(void) | ||
140 | { | ||
141 | return; | ||
142 | } | ||
143 | |||
144 | Uint32 SDL_ThreadID(void) | ||
145 | { | ||
146 | return((Uint32)GetCurrentThreadId()); | ||
147 | } | ||
148 | |||
149 | void SDL_SYS_WaitThread(SDL_Thread *thread) | ||
150 | { | ||
151 | WaitForSingleObject(thread->handle, INFINITE); | ||
152 | CloseHandle(thread->handle); | ||
153 | } | ||
154 | |||
155 | /* WARNING: This function is really a last resort. | ||
156 | * Threads should be signaled and then exit by themselves. | ||
157 | * TerminateThread() doesn't perform stack and DLL cleanup. | ||
158 | */ | ||
159 | void SDL_SYS_KillThread(SDL_Thread *thread) | ||
160 | { | ||
161 | TerminateThread(thread->handle, FALSE); | ||
162 | } | ||
diff --git a/apps/plugins/sdl/src/thread/win32/SDL_systhread_c.h b/apps/plugins/sdl/src/thread/win32/SDL_systhread_c.h deleted file mode 100644 index 10b0a7d6b5..0000000000 --- a/apps/plugins/sdl/src/thread/win32/SDL_systhread_c.h +++ /dev/null | |||
@@ -1,28 +0,0 @@ | |||
1 | /* | ||
2 | SDL - Simple DirectMedia Layer | ||
3 | Copyright (C) 1997-2012 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@libsdl.org | ||
21 | */ | ||
22 | #include "SDL_config.h" | ||
23 | |||
24 | #define WIN32_LEAN_AND_MEAN | ||
25 | #include <windows.h> | ||
26 | |||
27 | typedef HANDLE SYS_ThreadHandle; | ||
28 | |||
diff --git a/apps/plugins/sdl/src/thread/win32/win_ce_semaphore.c b/apps/plugins/sdl/src/thread/win32/win_ce_semaphore.c deleted file mode 100644 index 9db45c4391..0000000000 --- a/apps/plugins/sdl/src/thread/win32/win_ce_semaphore.c +++ /dev/null | |||
@@ -1,216 +0,0 @@ | |||
1 | /* win_ce_semaphore.c | ||
2 | |||
3 | Copyright (c) 1998, Johnson M. Hart | ||
4 | (with corrections 2001 by Rainer Loritz) | ||
5 | Permission is granted for any and all use providing that this | ||
6 | copyright is properly acknowledged. | ||
7 | There are no assurances of suitability for any use whatsoever. | ||
8 | |||
9 | WINDOWS CE: There is a collection of Windows CE functions to simulate | ||
10 | semaphores using only a mutex and an event. As Windows CE events cannot | ||
11 | be named, these simulated semaphores cannot be named either. | ||
12 | |||
13 | Implementation notes: | ||
14 | 1. All required internal data structures are allocated on the process's heap. | ||
15 | 2. Where appropriate, a new error code is returned (see the header | ||
16 | file), or, if the error is a Win32 error, that code is unchanged. | ||
17 | 3. Notice the new handle type "SYNCHHANDLE" that has handles, counters, | ||
18 | and other information. This structure will grow as new objects are added | ||
19 | to this set; some members are specific to only one or two of the objects. | ||
20 | 4. Mutexes are used for critical sections. These could be replaced with | ||
21 | CRITICAL_SECTION objects but then this would give up the time out | ||
22 | capability. | ||
23 | 5. The implementation shows several interesting aspects of synchronization, some | ||
24 | of which are specific to Win32 and some of which are general. These are pointed | ||
25 | out in the comments as appropriate. | ||
26 | 6. The wait function emulates WaitForSingleObject only. An emulation of | ||
27 | WaitForMultipleObjects is much harder to implement outside the kernel, | ||
28 | and it is not clear how to handle a mixture of WCE semaphores and normal | ||
29 | events and mutexes. */ | ||
30 | |||
31 | #define WIN32_LEAN_AND_MEAN | ||
32 | #include <windows.h> | ||
33 | |||
34 | #include "win_ce_semaphore.h" | ||
35 | |||
36 | static SYNCHHANDLE CleanUp (SYNCHHANDLE hSynch, DWORD Flags); | ||
37 | |||
38 | SYNCHHANDLE CreateSemaphoreCE ( | ||
39 | |||
40 | LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, /* pointer to security attributes */ | ||
41 | LONG lInitialCount, /* initial count */ | ||
42 | LONG lMaximumCount, /* maximum count */ | ||
43 | LPCTSTR lpName ) | ||
44 | |||
45 | /* Semaphore for use with Windows CE that does not support them directly. | ||
46 | Requires a counter, a mutex to protect the counter, and an | ||
47 | autoreset event. | ||
48 | |||
49 | Here are the rules that must always hold between the autoreset event | ||
50 | and the mutex (any violation of these rules by the CE semaphore functions | ||
51 | will, in all likelihood, result in a defect): | ||
52 | 1. No thread can set, pulse, or reset the event, | ||
53 | nor can it access any part of the SYNCHHANDLE structure, | ||
54 | without first gaining ownership of the mutex. | ||
55 | BUT, a thread can wait on the event without owning the mutex | ||
56 | (this is clearly necessary or else the event could never be set). | ||
57 | 2. The event is in a signaled state if and only if the current semaphore | ||
58 | count ("CurCount") is greater than zero. | ||
59 | 3. The semaphore count is always >= 0 and <= the maximum count */ | ||
60 | |||
61 | { | ||
62 | SYNCHHANDLE hSynch = NULL, result = NULL; | ||
63 | |||
64 | __try | ||
65 | { | ||
66 | if (lInitialCount > lMaximumCount || lMaximumCount < 0 || lInitialCount < 0) | ||
67 | { | ||
68 | /* Bad parameters */ | ||
69 | SetLastError (SYNCH_ERROR); | ||
70 | __leave; | ||
71 | } | ||
72 | |||
73 | hSynch = HeapAlloc (GetProcessHeap(), HEAP_ZERO_MEMORY, SYNCH_HANDLE_SIZE); | ||
74 | if (hSynch == NULL) __leave; | ||
75 | |||
76 | hSynch->MaxCount = lMaximumCount; | ||
77 | hSynch->CurCount = lInitialCount; | ||
78 | hSynch->lpName = lpName; | ||
79 | |||
80 | hSynch->hMutex = CreateMutex (lpSemaphoreAttributes, FALSE, NULL); | ||
81 | |||
82 | WaitForSingleObject (hSynch->hMutex, INFINITE); | ||
83 | /* Create the event. It is initially signaled if and only if the | ||
84 | initial count is > 0 */ | ||
85 | hSynch->hEvent = CreateEvent (lpSemaphoreAttributes, FALSE, | ||
86 | lInitialCount > 0, NULL); | ||
87 | ReleaseMutex (hSynch->hMutex); | ||
88 | hSynch->hSemph = NULL; | ||
89 | } | ||
90 | __finally | ||
91 | { | ||
92 | /* Return with the handle, or, if there was any error, return | ||
93 | a null after closing any open handles and freeing any allocated memory. */ | ||
94 | result=CleanUp(hSynch, 6 /* An event and a mutex, but no semaphore. */); | ||
95 | } | ||
96 | |||
97 | return result; | ||
98 | } | ||
99 | |||
100 | BOOL ReleaseSemaphoreCE (SYNCHHANDLE hSemCE, LONG cReleaseCount, LPLONG lpPreviousCount) | ||
101 | /* Windows CE equivalent to ReleaseSemaphore. */ | ||
102 | { | ||
103 | BOOL Result = TRUE; | ||
104 | |||
105 | /* Gain access to the object to assure that the release count | ||
106 | would not cause the total count to exceed the maximum. */ | ||
107 | |||
108 | __try | ||
109 | { | ||
110 | WaitForSingleObject (hSemCE->hMutex, INFINITE); | ||
111 | /* reply only if asked to */ | ||
112 | if (lpPreviousCount!=NULL) | ||
113 | *lpPreviousCount = hSemCE->CurCount; | ||
114 | if (hSemCE->CurCount + cReleaseCount > hSemCE->MaxCount || cReleaseCount <= 0) | ||
115 | { | ||
116 | SetLastError (SYNCH_ERROR); | ||
117 | Result = FALSE; | ||
118 | __leave; | ||
119 | } | ||
120 | hSemCE->CurCount += cReleaseCount; | ||
121 | |||
122 | /* Set the autoreset event, releasing exactly one waiting thread, now or | ||
123 | in the future. */ | ||
124 | |||
125 | SetEvent (hSemCE->hEvent); | ||
126 | } | ||
127 | __finally | ||
128 | { | ||
129 | ReleaseMutex (hSemCE->hMutex); | ||
130 | } | ||
131 | |||
132 | return Result; | ||
133 | } | ||
134 | |||
135 | DWORD WaitForSemaphoreCE (SYNCHHANDLE hSemCE, DWORD dwMilliseconds) | ||
136 | /* Windows CE semaphore equivalent of WaitForSingleObject. */ | ||
137 | { | ||
138 | DWORD WaitResult; | ||
139 | |||
140 | WaitResult = WaitForSingleObject (hSemCE->hMutex, dwMilliseconds); | ||
141 | if (WaitResult != WAIT_OBJECT_0 && WaitResult != WAIT_ABANDONED_0) return WaitResult; | ||
142 | while (hSemCE->CurCount <= 0) | ||
143 | { | ||
144 | |||
145 | /* The count is 0, and the thread must wait on the event (which, by | ||
146 | the rules, is currently reset) for semaphore resources to become | ||
147 | available. First, of course, the mutex must be released so that another | ||
148 | thread will be capable of setting the event. */ | ||
149 | |||
150 | ReleaseMutex (hSemCE->hMutex); | ||
151 | |||
152 | /* Wait for the event to be signaled, indicating a semaphore state change. | ||
153 | The event is autoreset and signaled with a SetEvent (not PulseEvent) | ||
154 | so exactly one waiting thread (whether or not there is currently | ||
155 | a waiting thread) is released as a result of the SetEvent. */ | ||
156 | |||
157 | WaitResult = WaitForSingleObject (hSemCE->hEvent, dwMilliseconds); | ||
158 | if (WaitResult != WAIT_OBJECT_0) return WaitResult; | ||
159 | |||
160 | /* This is where the properties of setting of an autoreset event is critical | ||
161 | to assure that, even if the semaphore state changes between the | ||
162 | preceding Wait and the next, and even if NO threads are waiting | ||
163 | on the event at the time of the SetEvent, at least one thread | ||
164 | will be released. | ||
165 | Pulsing a manual reset event would appear to work, but it would have | ||
166 | a defect which could appear if the semaphore state changed between | ||
167 | the two waits. */ | ||
168 | |||
169 | WaitResult = WaitForSingleObject (hSemCE->hMutex, dwMilliseconds); | ||
170 | if (WaitResult != WAIT_OBJECT_0 && WaitResult != WAIT_ABANDONED_0) return WaitResult; | ||
171 | |||
172 | } | ||
173 | /* The count is not zero and this thread owns the mutex. */ | ||
174 | |||
175 | hSemCE->CurCount--; | ||
176 | /* The event is now unsignaled, BUT, the semaphore count may not be | ||
177 | zero, in which case the event should be signaled again | ||
178 | before releasing the mutex. */ | ||
179 | |||
180 | if (hSemCE->CurCount > 0) SetEvent (hSemCE->hEvent); | ||
181 | ReleaseMutex (hSemCE->hMutex); | ||
182 | return WaitResult; | ||
183 | } | ||
184 | |||
185 | BOOL CloseSynchHandle (SYNCHHANDLE hSynch) | ||
186 | /* Close a synchronization handle. | ||
187 | Improvement: Test for a valid handle before dereferencing the handle. */ | ||
188 | { | ||
189 | BOOL Result = TRUE; | ||
190 | if (hSynch->hEvent != NULL) Result = Result && CloseHandle (hSynch->hEvent); | ||
191 | if (hSynch->hMutex != NULL) Result = Result && CloseHandle (hSynch->hMutex); | ||
192 | if (hSynch->hSemph != NULL) Result = Result && CloseHandle (hSynch->hSemph); | ||
193 | HeapFree (GetProcessHeap (), 0, hSynch); | ||
194 | return (Result); | ||
195 | } | ||
196 | |||
197 | static SYNCHHANDLE CleanUp (SYNCHHANDLE hSynch, DWORD Flags) | ||
198 | { /* Prepare to return from a create of a synchronization handle. | ||
199 | If there was any failure, free any allocated resources. | ||
200 | "Flags" indicates which Win32 objects are required in the | ||
201 | synchronization handle. */ | ||
202 | |||
203 | BOOL ok = TRUE; | ||
204 | |||
205 | if (hSynch == NULL) return NULL; | ||
206 | if ((Flags & 4) == 1 && (hSynch->hEvent == NULL)) ok = FALSE; | ||
207 | if ((Flags & 2) == 1 && (hSynch->hMutex == NULL)) ok = FALSE; | ||
208 | if ((Flags & 1) == 1 && (hSynch->hEvent == NULL)) ok = FALSE; | ||
209 | if (!ok) | ||
210 | { | ||
211 | CloseSynchHandle (hSynch); | ||
212 | return NULL; | ||
213 | } | ||
214 | /* Everything worked */ | ||
215 | return hSynch; | ||
216 | } | ||
diff --git a/apps/plugins/sdl/src/thread/win32/win_ce_semaphore.h b/apps/plugins/sdl/src/thread/win32/win_ce_semaphore.h deleted file mode 100644 index af2d7b613d..0000000000 --- a/apps/plugins/sdl/src/thread/win32/win_ce_semaphore.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | /* win_ce_semaphore.h - header file to go with win_ce_semaphore.c */ | ||
2 | |||
3 | typedef struct _SYNCH_HANDLE_STRUCTURE { | ||
4 | HANDLE hEvent; | ||
5 | HANDLE hMutex; | ||
6 | HANDLE hSemph; | ||
7 | LONG MaxCount; | ||
8 | volatile LONG CurCount; | ||
9 | LPCTSTR lpName; | ||
10 | } SYNCH_HANDLE_STRUCTURE, *SYNCHHANDLE; | ||
11 | |||
12 | #define SYNCH_HANDLE_SIZE sizeof (SYNCH_HANDLE_STRUCTURE) | ||
13 | |||
14 | /* Error codes - all must have bit 29 set */ | ||
15 | #define SYNCH_ERROR 0X20000000 /* EXERCISE - REFINE THE ERROR NUMBERS */ | ||
16 | |||
17 | extern SYNCHHANDLE CreateSemaphoreCE (LPSECURITY_ATTRIBUTES, LONG, LONG, LPCTSTR); | ||
18 | |||
19 | extern BOOL ReleaseSemaphoreCE (SYNCHHANDLE, LONG, LPLONG); | ||
20 | extern DWORD WaitForSemaphoreCE (SYNCHHANDLE, DWORD); | ||
21 | |||
22 | extern BOOL CloseSynchHandle (SYNCHHANDLE); | ||