aboutsummaryrefslogtreecommitdiff
path: root/Src/Wasabi/bfc/thread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Wasabi/bfc/thread.cpp')
-rw-r--r--Src/Wasabi/bfc/thread.cpp124
1 files changed, 124 insertions, 0 deletions
diff --git a/Src/Wasabi/bfc/thread.cpp b/Src/Wasabi/bfc/thread.cpp
new file mode 100644
index 00000000..3306c1bd
--- /dev/null
+++ b/Src/Wasabi/bfc/thread.cpp
@@ -0,0 +1,124 @@
+#include "precomp_wasabi_bfc.h"
+
+#include "thread.h"
+
+#if !defined(WIN32) && !defined(LINUX)
+#error port me!
+#endif
+
+#pragma warning(push)
+#pragma warning(disable : 4229)
+
+THREADCALL Thread::ThreadProc(void *param) {
+ Thread *th = static_cast<Thread*>(param);
+ th->isrunning = true;
+ int ret = th->threadProc();
+ th->isrunning = false;
+ return (THREADCALL)ret;
+}
+
+#pragma warning(pop)
+
+Thread::Thread(HANDLE _parent_handle) :
+ isrunning(false),
+ killswitch(0),
+ handle(0), parent_handle(0), nicekill(1),
+ auto_close_parent(FALSE)
+{
+ setParentHandle(_parent_handle);
+#ifdef WIN32
+ handle = CreateThread(NULL, 0, ThreadProc, (LPVOID)this, CREATE_SUSPENDED, &threadid);
+#endif
+}
+
+Thread::~Thread() {
+ if (handle != 0) {
+ if (isrunning) {
+ setKillSwitch(TRUE);
+ end();
+ // FUCKO: might need to get rough here
+ // FG> this serves no purpose, end() will not return unless the thread exits nicely
+ #ifdef WIN32
+ CloseHandle(handle);
+ #elif defined(LINUX)
+ pthread_kill(handle, SIGTERM);
+ #endif
+ }
+ }
+ setParentHandle(0);
+}
+
+int Thread::start() {
+ if (running()) return 1;
+#ifdef WIN32
+ return !(ResumeThread(handle) == 0xffffffff);
+#endif
+#ifdef LINUX
+ pthread_create(&handle, NULL, ThreadProc, (LPVOID)this);
+ return 1;
+#endif
+}
+
+bool Thread::running() {
+ return isrunning;
+}
+
+int Thread::end() {
+ while (running()) Sleep(66);
+ return 1;
+}
+
+int Thread::kill() {
+#ifdef WIN32
+ CloseHandle(handle);
+#elif defined(LINUX)
+ pthread_kill(handle, SIGTERM);
+#endif
+ handle = 0;
+ isrunning = false;
+ return 1;
+}
+
+void Thread::setKillSwitch(int k) {
+ killswitch = k;
+}
+
+int Thread::getKillSwitch() {
+ if (killswitch) return 1;
+ if (parent_handle != 0 && !parentRunning()) return 1;
+ return 0;
+}
+
+THREADID Thread::getThreadId() const {
+ return threadid;
+}
+
+void Thread::setParentHandle(HANDLE _parent_handle, int _auto_close) {
+ if (parent_handle != 0 && auto_close_parent) {
+#ifdef WIN32
+ CloseHandle(parent_handle);
+#else
+//#error port me!
+ DebugString("setParentHandle???\n");
+#endif
+ }
+ parent_handle = _parent_handle;
+ auto_close_parent = _auto_close;
+}
+
+int Thread::parentRunning() {
+ if (parent_handle == 0) return -1;
+#ifdef WIN32
+ DWORD exitcode;
+ int r = GetExitCodeThread(parent_handle, &exitcode);
+ if (r == 0 || exitcode != STILL_ACTIVE) return 0;
+ return 1;
+#else
+//#error port me!
+ DebugString("parentRunning???\n");
+#endif
+}
+
+void Thread::setPriority(int priority) {
+ Wasabi::Std::setThreadPriority(priority, handle);
+}