summaryrefslogtreecommitdiffstats
path: root/libdash/source/portable
diff options
context:
space:
mode:
Diffstat (limited to 'libdash/source/portable')
-rw-r--r--libdash/source/portable/MultiThreading.cpp112
-rw-r--r--libdash/source/portable/MultiThreading.h70
-rw-r--r--libdash/source/portable/Networking.h27
3 files changed, 209 insertions, 0 deletions
diff --git a/libdash/source/portable/MultiThreading.cpp b/libdash/source/portable/MultiThreading.cpp
new file mode 100644
index 00000000..5d1fe9c0
--- /dev/null
+++ b/libdash/source/portable/MultiThreading.cpp
@@ -0,0 +1,112 @@
+#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;
+ }
+
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+ if(int err = pthread_create(th, &attr, 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);
+ #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
diff --git a/libdash/source/portable/MultiThreading.h b/libdash/source/portable/MultiThreading.h
new file mode 100644
index 00000000..c1b45f5c
--- /dev/null
+++ b/libdash/source/portable/MultiThreading.h
@@ -0,0 +1,70 @@
+#ifndef PORTABLE_MULTITHREADING_H_
+#define PORTABLE_MULTITHREADING_H_
+
+#if defined _WIN32 || defined _WIN64
+
+ #define _WINSOCKAPI_
+ #include <Windows.h>
+ #define DeleteConditionVariable(cond_p) {}
+
+ typedef HANDLE THREAD_HANDLE;
+
+ #if defined WINXPOROLDER
+ /****************************************************************************
+ * Variables
+ *****************************************************************************/
+ struct condition_variable_t
+ {
+ int waitersCount; // Count of the number of waiters.
+ CRITICAL_SECTION waitersCountLock; // Serialize access to <waitersCount>.
+ int releaseCount; // Number of threads to release via a <BroadcastCondition> or a <SignalCondition>.
+ int waitGenerationCount; // Keeps track of the current "generation" so that we don't allow one thread to steal all the "releases" from the broadcast.
+ HANDLE waitingEvent; // A manual-reset event that's used to block and release waiting threads.
+ };
+ /****************************************************************************
+ * Prototypes
+ *****************************************************************************/
+ void InitCondition (condition_variable_t *cv);
+ void WaitCondition (condition_variable_t *cv, CRITICAL_SECTION *externalMutex);
+ void SignalCondition (condition_variable_t *cv);
+ void BroadcastCondition (condition_variable_t *cv);
+ /****************************************************************************
+ * Defines
+ *****************************************************************************/
+ #define CONDITION_VARIABLE condition_variable_t
+
+ #define InitializeConditionVariable(cond_p) InitCondition(cond_p)
+ #define SleepConditionVariableCS(cond_p, mutex_p, infinite) WaitCondition(cond_p, mutex_p) // INFINITE should be handled mor properly
+ #define WakeConditionVariable(cond_p) SignalCondition(cond_p)
+ #define WakeAllConditionVariable(cond_p) BroadcastCondition(cond_p)
+ #endif
+
+#else
+
+ #include <string.h>
+ #include <pthread.h>
+ #include <errno.h>
+ #include <stdlib.h>
+ #include <iostream>
+
+ #define CRITICAL_SECTION pthread_mutex_t
+ #define CONDITION_VARIABLE pthread_cond_t
+
+ #define InitializeCriticalSection(mutex_p) pthread_mutex_init(mutex_p, NULL)
+ #define DeleteCriticalSection(mutex_p) pthread_mutex_destroy(mutex_p)
+ #define EnterCriticalSection(mutex_p) pthread_mutex_lock(mutex_p)
+ #define LeaveCriticalSection(mutex_p) pthread_mutex_unlock(mutex_p)
+ #define InitializeConditionVariable(cond_p) pthread_cond_init(cond_p, NULL)
+ #define DeleteConditionVariable(cond_p) pthread_cond_destroy(cond_p)
+ #define SleepConditionVariableCS(cond_p, mutex_p, infinite) pthread_cond_wait(cond_p, mutex_p) // INFINITE should be handled mor properly
+ #define WakeConditionVariable(cond_p) pthread_cond_signal(cond_p)
+ #define WakeAllConditionVariable(cond_p) pthread_cond_broadcast(cond_p)
+
+ typedef pthread_t* THREAD_HANDLE;
+
+#endif
+
+THREAD_HANDLE CreateThreadPortable (void *(*start_routine) (void *), void *arg);
+void DestroyThreadPortable (THREAD_HANDLE th);
+
+#endif // PORTABLE_MULTITHREADING_H_ \ No newline at end of file
diff --git a/libdash/source/portable/Networking.h b/libdash/source/portable/Networking.h
new file mode 100644
index 00000000..6239c3a3
--- /dev/null
+++ b/libdash/source/portable/Networking.h
@@ -0,0 +1,27 @@
+#ifndef PORTABLE_NETWORKING_H_
+#define PORTABLE_NETWORKING_H_
+
+#if defined _WIN32 || defined _WIN64
+
+#include <WinSock2.h>
+#include <WS2tcpip.h>
+
+#else
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/ip.h> /* superset of previous */
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#define closesocket(socket) close(socket)
+#define WSAStartup(wVersionRequested, lpWSAData) 0
+#define WSACleanup() {}
+
+typedef unsigned char WSADATA;
+
+#endif
+
+#endif // PORTABLE_NETWORKING_H_