summaryrefslogtreecommitdiffstats
path: root/Portable/MultiThreading.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Portable/MultiThreading.cpp')
-rw-r--r--Portable/MultiThreading.cpp120
1 files changed, 120 insertions, 0 deletions
diff --git a/Portable/MultiThreading.cpp b/Portable/MultiThreading.cpp
new file mode 100644
index 00000000..fd5dc14d
--- /dev/null
+++ b/Portable/MultiThreading.cpp
@@ -0,0 +1,120 @@
+/*
+ * MultiThreading.cpp
+ *****************************************************************************
+ * Copyright (C) 2012, bitmovin Softwareentwicklung OG, All Rights Reserved
+ *
+ * Email: libdash-dev@vicky.bitmovin.net
+ *
+ * This source code and its use and distribution, is subject to the terms
+ * and conditions of the applicable license agreement.
+ *****************************************************************************/
+
+#include "MultiThreading.h"
+
+THREAD_HANDLE createThreadPortable(void *(*start_routine) (void *), void *arg)
+{
+#if defined _WIN32 || defined _WIN64
+ return CreateThread (0, 0, (LPTHREAD_START_ROUTINE)start_routine, (LPVOID)arg, 0, 0);
+#else
+ THREAD_HANDLE th = (THREAD_HANDLE)malloc(sizeof(pthread_t));
+ if (!th)
+ {
+ std::cerr << "Error allocating thread." << std::endl;
+ return NULL;
+ }
+
+ if(int err = pthread_create(th, NULL, start_routine, arg))
+ {
+ std::cerr << strerror(err) << std::endl;
+ return NULL;
+ }
+ return th;
+#endif
+}
+void destroyThreadPortable(THREAD_HANDLE th)
+{
+#if !defined _WIN32 && !defined _WIN64
+ if(th)
+ free(th);
+#else
+ CloseHandle(th);
+#endif
+}
+
+/****************************************************************************
+* Condition variables for Windows XP and older windows sytems
+*****************************************************************************/
+#if defined WINXPOROLDER
+void InitCondition (condition_variable_t *cv)
+{
+ InitializeCriticalSection(&cv->waitersCountLock);
+
+ cv->waitersCount = 0;
+ cv->waitGenerationCount = 0;
+ cv->releaseCount = 0;
+
+ cv->waitingEvent = CreateEvent (NULL, // no security
+ TRUE, // manual-reset
+ FALSE, // non-signaled initially
+ NULL); // unnamed
+}
+void WaitCondition (condition_variable_t *cv, CRITICAL_SECTION *externalMutex)
+{
+ EnterCriticalSection(&cv->waitersCountLock);
+
+ cv->waitersCount++;
+
+ int currentGenerationCount = cv->waitGenerationCount;
+
+ LeaveCriticalSection(&cv->waitersCountLock);
+ LeaveCriticalSection(externalMutex);
+
+ bool isWaitDone = false;
+ while(!isWaitDone)
+ {
+ WaitForSingleObject (cv->waitingEvent, INFINITE);
+ EnterCriticalSection (&cv->waitersCountLock);
+
+ isWaitDone = (cv->releaseCount > 0 && cv->waitGenerationCount != currentGenerationCount);
+ LeaveCriticalSection (&cv->waitersCountLock);
+ }
+
+ EnterCriticalSection(externalMutex);
+ EnterCriticalSection(&cv->waitersCountLock);
+
+ cv->waitersCount--;
+ cv->releaseCount--;
+ bool isLastWaiter = (cv->releaseCount == 0);
+
+ LeaveCriticalSection(&cv->waitersCountLock);
+
+ if(isLastWaiter)
+ ResetEvent(cv->waitingEvent);
+}
+void SignalCondition (condition_variable_t *cv)
+{
+ EnterCriticalSection(&cv->waitersCountLock);
+
+ if(cv->waitersCount > cv->releaseCount)
+ {
+ SetEvent(cv->waitingEvent);
+ cv->releaseCount++;
+ cv->waitGenerationCount++;
+ }
+
+ LeaveCriticalSection(&cv->waitersCountLock);
+}
+void BroadcastCondition (condition_variable_t *cv)
+{
+ EnterCriticalSection(&cv->waitersCountLock);
+
+ if(cv->waitersCount > 0)
+ {
+ SetEvent(cv->waitingEvent);
+ cv->releaseCount = cv->waitersCount;
+ cv->waitGenerationCount++;
+ }
+
+ LeaveCriticalSection(&cv->waitersCountLock);
+}
+#endif