From 1da742f010cfc37e0c311ca63f99886908ff0393 Mon Sep 17 00:00:00 2001 From: orudge Date: Mon, 16 Mar 2009 20:05:24 +0000 Subject: (svn r15746) -Fix: Update threading code for OS/2, add mutex support --- src/thread_os2.cpp | 138 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 94 insertions(+), 44 deletions(-) diff --git a/src/thread_os2.cpp b/src/thread_os2.cpp index 9d05f7e02..9d494af39 100644 --- a/src/thread_os2.cpp +++ b/src/thread_os2.cpp @@ -1,66 +1,116 @@ /* $Id$ */ -/** @file thread_os2.cpp OS2 implementation of Threads. */ +/** @file thread_os2.cpp OS/2 implementation of Threads. */ #include "stdafx.h" #include "thread.h" -#if 0 -#include "debug.h" -#include "core/alloc_func.hpp" -#include - #define INCL_DOS #include #include -struct OTTDThread { - TID thread; - OTTDThreadFunc func; - void *arg; - void *ret; -}; +/** + * OS/2 version for ThreadObject. + */ +class ThreadObject_OS2 : public ThreadObject { +private: + TID thread; ///< System thread identifier. + OTTDThreadFunc proc; ///< External thread procedure. + void *param; ///< Parameter for the external thread procedure. + bool self_destruct; ///< Free ourselves when done? -static void Proxy(void *arg) -{ - OTTDThread *t = (OTTDThread *)arg; - t->ret = t->func(t->arg); -} +public: + /** + * Create a thread and start it, calling proc(param). + */ + ThreadObject_OS2(OTTDThreadFunc proc, void *param, bool self_destruct) : + thread(0), + proc(proc), + param(param), + self_destruct(self_destruct) + { + thread = _beginthread(stThreadProc, NULL, 32768, this); + } -OTTDThread *OTTDCreateThread(OTTDThreadFunc function, void *arg) -{ - OTTDThread *t = MallocT(1); - - t->func = function; - t->arg = arg; - t->thread = _beginthread(Proxy, NULL, 32768, t); - if (t->thread != (TID)-1) { - return t; - } else { - free(t); - return NULL; + /* virtual */ bool Exit() + { + _endthread(); + return true; } -} -void *OTTDJoinThread(OTTDThread *t) -{ - if (t == NULL) return NULL; + /* virtual */ void Join() + { + DosWaitThread(&this->thread, DCWW_WAIT); + this->thread = 0; + } +private: + /** + * On thread creation, this function is called, which calls the real startup + * function. This to get back into the correct instance again. + */ + static void stThreadProc(void *thr) + { + ((ThreadObject_OS2 *)thr)->ThreadProc(); + } - DosWaitThread(&t->thread, DCWW_WAIT); - void *ret = t->ret; - free(t); - return ret; -} + /** + * A new thread is created, and this function is called. Call the custom + * function of the creator of the thread. + */ + void ThreadProc() + { + /* Call the proc of the creator to continue this thread */ + try { + this->proc(this->param); + } catch (OTTDThreadExitSignal e) { + } catch (...) { + NOT_REACHED(); + } -void OTTDExitThread() + if (self_destruct) { + this->Exit(); + delete this; + } + } +}; + +/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread) { - _endthread(); + ThreadObject *to = new ThreadObject_OS2(proc, param, thread == NULL); + if (thread != NULL) *thread = to; + return true; } -#endif +/** + * OS/2 version of ThreadMutex. + */ +class ThreadMutex_OS2 : public ThreadMutex { +private: + HMTX mutex; + +public: + ThreadMutex_OS2() + { + DosCreateMutexSem(NULL, &mutex, 0, FALSE); + } + + /* virtual */ ~ThreadMutex_OS2() + { + DosCloseMutexSem(mutex); + } + + /* virtual */ void BeginCritical() + { + DosRequestMutexSem(mutex, (unsigned long) SEM_INDEFINITE_WAIT); + } + + /* virtual */ void EndCritical() + { + DosReleaseMutexSem(mutex); + } +}; -/* static */ ThreadObject *ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread) +/* static */ ThreadMutex *ThreadMutex::New() { - if (thread != NULL) *thread = NULL; - return false; + return new ThreadMutex_OS2(); } -- cgit v1.2.3-54-g00ecf