diff options
author | orudge <orudge@openttd.org> | 2009-03-16 20:05:24 +0000 |
---|---|---|
committer | orudge <orudge@openttd.org> | 2009-03-16 20:05:24 +0000 |
commit | 1da742f010cfc37e0c311ca63f99886908ff0393 (patch) | |
tree | e3d20b136d07392e3a8f40a48843796e43946d32 | |
parent | de67610a7ad6552be2b2d0b4dae25a3d09c265be (diff) | |
download | openttd-1da742f010cfc37e0c311ca63f99886908ff0393.tar.xz |
(svn r15746) -Fix: Update threading code for OS/2, add mutex support
-rw-r--r-- | src/thread_os2.cpp | 138 |
1 files 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 <stdlib.h> - #define INCL_DOS #include <os2.h> #include <process.h> -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<OTTDThread>(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(); } |