summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/SDL2/src/thread/stdcpp/SDL_syscond.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/SDL2/src/thread/stdcpp/SDL_syscond.cpp')
-rw-r--r--3rdparty/SDL2/src/thread/stdcpp/SDL_syscond.cpp164
1 files changed, 164 insertions, 0 deletions
diff --git a/3rdparty/SDL2/src/thread/stdcpp/SDL_syscond.cpp b/3rdparty/SDL2/src/thread/stdcpp/SDL_syscond.cpp
new file mode 100644
index 00000000000..976bff48792
--- /dev/null
+++ b/3rdparty/SDL2/src/thread/stdcpp/SDL_syscond.cpp
@@ -0,0 +1,164 @@
+/*
+ Simple DirectMedia Layer
+ Copyright (C) 1997-2016 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"
+
+extern "C" {
+#include "SDL_thread.h"
+}
+
+#include <chrono>
+#include <condition_variable>
+#include <ratio>
+#include <system_error>
+
+#include "SDL_sysmutex_c.h"
+
+struct SDL_cond
+{
+ std::condition_variable_any cpp_cond;
+};
+
+/* Create a condition variable */
+extern "C"
+SDL_cond *
+SDL_CreateCond(void)
+{
+ /* Allocate and initialize the condition variable */
+ try {
+ SDL_cond * cond = new SDL_cond;
+ return cond;
+ } catch (std::system_error & ex) {
+ SDL_SetError("unable to create a C++ condition variable: code=%d; %s", ex.code(), ex.what());
+ return NULL;
+ } catch (std::bad_alloc &) {
+ SDL_OutOfMemory();
+ return NULL;
+ }
+}
+
+/* Destroy a condition variable */
+extern "C"
+void
+SDL_DestroyCond(SDL_cond * cond)
+{
+ if (cond) {
+ delete cond;
+ }
+}
+
+/* Restart one of the threads that are waiting on the condition variable */
+extern "C"
+int
+SDL_CondSignal(SDL_cond * cond)
+{
+ if (!cond) {
+ SDL_SetError("Passed a NULL condition variable");
+ return -1;
+ }
+
+ cond->cpp_cond.notify_one();
+ return 0;
+}
+
+/* Restart all threads that are waiting on the condition variable */
+extern "C"
+int
+SDL_CondBroadcast(SDL_cond * cond)
+{
+ if (!cond) {
+ SDL_SetError("Passed a NULL condition variable");
+ return -1;
+ }
+
+ cond->cpp_cond.notify_all();
+ return 0;
+}
+
+/* Wait on the condition variable for at most 'ms' milliseconds.
+ The mutex must be locked before entering this function!
+ The mutex is unlocked during the wait, and locked again after the wait.
+
+Typical use:
+
+Thread A:
+ SDL_LockMutex(lock);
+ while ( ! condition ) {
+ SDL_CondWait(cond, lock);
+ }
+ SDL_UnlockMutex(lock);
+
+Thread B:
+ SDL_LockMutex(lock);
+ ...
+ condition = true;
+ ...
+ SDL_CondSignal(cond);
+ SDL_UnlockMutex(lock);
+ */
+extern "C"
+int
+SDL_CondWaitTimeout(SDL_cond * cond, SDL_mutex * mutex, Uint32 ms)
+{
+ if (!cond) {
+ SDL_SetError("Passed a NULL condition variable");
+ return -1;
+ }
+
+ if (!mutex) {
+ SDL_SetError("Passed a NULL mutex variable");
+ return -1;
+ }
+
+ try {
+ std::unique_lock<std::recursive_mutex> cpp_lock(mutex->cpp_mutex, std::adopt_lock_t());
+ if (ms == SDL_MUTEX_MAXWAIT) {
+ cond->cpp_cond.wait(
+ cpp_lock
+ );
+ cpp_lock.release();
+ return 0;
+ } else {
+ auto wait_result = cond->cpp_cond.wait_for(
+ cpp_lock,
+ std::chrono::duration<Uint32, std::milli>(ms)
+ );
+ cpp_lock.release();
+ if (wait_result == std::cv_status::timeout) {
+ return SDL_MUTEX_TIMEDOUT;
+ } else {
+ return 0;
+ }
+ }
+ } catch (std::system_error & ex) {
+ SDL_SetError("unable to wait on a C++ condition variable: code=%d; %s", ex.code(), ex.what());
+ return -1;
+ }
+}
+
+/* Wait on the condition variable forever */
+extern "C"
+int
+SDL_CondWait(SDL_cond * cond, SDL_mutex * mutex)
+{
+ return SDL_CondWaitTimeout(cond, mutex, SDL_MUTEX_MAXWAIT);
+}
+
+/* vi: set ts=4 sw=4 expandtab: */