summaryrefslogtreecommitdiff
path: root/source/3rd-party/SDL2/src/thread/windows/SDL_syssem.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/3rd-party/SDL2/src/thread/windows/SDL_syssem.c')
-rw-r--r--source/3rd-party/SDL2/src/thread/windows/SDL_syssem.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/source/3rd-party/SDL2/src/thread/windows/SDL_syssem.c b/source/3rd-party/SDL2/src/thread/windows/SDL_syssem.c
new file mode 100644
index 0000000..dcb36fa
--- /dev/null
+++ b/source/3rd-party/SDL2/src/thread/windows/SDL_syssem.c
@@ -0,0 +1,152 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2018 Sam Lantinga <slouken@libsdl.org>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+*/
+#include "../../SDL_internal.h"
+
+#if SDL_THREAD_WINDOWS
+
+/* Semaphore functions using the Win32 API */
+
+#include "../../core/windows/SDL_windows.h"
+
+#include "SDL_thread.h"
+
+struct SDL_semaphore
+{
+ HANDLE id;
+ LONG count;
+};
+
+
+/* Create a semaphore */
+SDL_sem *
+SDL_CreateSemaphore(Uint32 initial_value)
+{
+ SDL_sem *sem;
+
+ /* Allocate sem memory */
+ sem = (SDL_sem *) SDL_malloc(sizeof(*sem));
+ if (sem) {
+ /* Create the semaphore, with max value 32K */
+#if __WINRT__
+ sem->id = CreateSemaphoreEx(NULL, initial_value, 32 * 1024, NULL, 0, SEMAPHORE_ALL_ACCESS);
+#else
+ sem->id = CreateSemaphore(NULL, initial_value, 32 * 1024, NULL);
+#endif
+ sem->count = initial_value;
+ if (!sem->id) {
+ SDL_SetError("Couldn't create semaphore");
+ SDL_free(sem);
+ sem = NULL;
+ }
+ } else {
+ SDL_OutOfMemory();
+ }
+ return (sem);
+}
+
+/* Free the semaphore */
+void
+SDL_DestroySemaphore(SDL_sem * sem)
+{
+ if (sem) {
+ if (sem->id) {
+ CloseHandle(sem->id);
+ sem->id = 0;
+ }
+ SDL_free(sem);
+ }
+}
+
+int
+SDL_SemWaitTimeout(SDL_sem * sem, Uint32 timeout)
+{
+ int retval;
+ DWORD dwMilliseconds;
+
+ if (!sem) {
+ return SDL_SetError("Passed a NULL sem");
+ }
+
+ if (timeout == SDL_MUTEX_MAXWAIT) {
+ dwMilliseconds = INFINITE;
+ } else {
+ dwMilliseconds = (DWORD) timeout;
+ }
+ switch (WaitForSingleObjectEx(sem->id, dwMilliseconds, FALSE)) {
+ case WAIT_OBJECT_0:
+ InterlockedDecrement(&sem->count);
+ retval = 0;
+ break;
+ case WAIT_TIMEOUT:
+ retval = SDL_MUTEX_TIMEDOUT;
+ break;
+ default:
+ retval = SDL_SetError("WaitForSingleObject() failed");
+ break;
+ }
+ return retval;
+}
+
+int
+SDL_SemTryWait(SDL_sem * sem)
+{
+ return SDL_SemWaitTimeout(sem, 0);
+}
+
+int
+SDL_SemWait(SDL_sem * sem)
+{
+ return SDL_SemWaitTimeout(sem, SDL_MUTEX_MAXWAIT);
+}
+
+/* Returns the current count of the semaphore */
+Uint32
+SDL_SemValue(SDL_sem * sem)
+{
+ if (!sem) {
+ SDL_SetError("Passed a NULL sem");
+ return 0;
+ }
+ return (Uint32)sem->count;
+}
+
+int
+SDL_SemPost(SDL_sem * sem)
+{
+ if (!sem) {
+ return SDL_SetError("Passed a NULL sem");
+ }
+ /* Increase the counter in the first place, because
+ * after a successful release the semaphore may
+ * immediately get destroyed by another thread which
+ * is waiting for this semaphore.
+ */
+ InterlockedIncrement(&sem->count);
+ if (ReleaseSemaphore(sem->id, 1, NULL) == FALSE) {
+ InterlockedDecrement(&sem->count); /* restore */
+ return SDL_SetError("ReleaseSemaphore() failed");
+ }
+ return 0;
+}
+
+#endif /* SDL_THREAD_WINDOWS */
+
+/* vi: set ts=4 sw=4 expandtab: */