Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00012 #include "../stdafx.h"
00013 #include "thread.h"
00014
00015 #define INCL_DOS
00016 #include <os2.h>
00017 #include <process.h>
00018
00022 class ThreadObject_OS2 : public ThreadObject {
00023 private:
00024 TID thread;
00025 OTTDThreadFunc proc;
00026 void *param;
00027 bool self_destruct;
00028
00029 public:
00033 ThreadObject_OS2(OTTDThreadFunc proc, void *param, bool self_destruct) :
00034 thread(0),
00035 proc(proc),
00036 param(param),
00037 self_destruct(self_destruct)
00038 {
00039 thread = _beginthread(stThreadProc, NULL, 32768, this);
00040 }
00041
00042 bool Exit()
00043 {
00044 _endthread();
00045 return true;
00046 }
00047
00048 void Join()
00049 {
00050 DosWaitThread(&this->thread, DCWW_WAIT);
00051 this->thread = 0;
00052 }
00053 private:
00058 static void stThreadProc(void *thr)
00059 {
00060 ((ThreadObject_OS2 *)thr)->ThreadProc();
00061 }
00062
00067 void ThreadProc()
00068 {
00069
00070 try {
00071 this->proc(this->param);
00072 } catch (OTTDThreadExitSignal e) {
00073 } catch (...) {
00074 NOT_REACHED();
00075 }
00076
00077 if (self_destruct) {
00078 this->Exit();
00079 delete this;
00080 }
00081 }
00082 };
00083
00084 bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread)
00085 {
00086 ThreadObject *to = new ThreadObject_OS2(proc, param, thread == NULL);
00087 if (thread != NULL) *thread = to;
00088 return true;
00089 }
00090
00094 class ThreadMutex_OS2 : public ThreadMutex {
00095 private:
00096 HMTX mutex;
00097 HEV event;
00098 uint recursive_count;
00099
00100 public:
00101 ThreadMutex_OS2() : recursive_count(0)
00102 {
00103 DosCreateMutexSem(NULL, &mutex, 0, FALSE);
00104 DosCreateEventSem(NULL, &event, 0, FALSE);
00105 }
00106
00107 ~ThreadMutex_OS2()
00108 {
00109 DosCloseMutexSem(mutex);
00110 DosCloseEventSem(event);
00111 }
00112
00113 void BeginCritical(bool allow_recursive = false)
00114 {
00115
00116 DosRequestMutexSem(mutex, (unsigned long) SEM_INDEFINITE_WAIT);
00117 this->recursive_count++;
00118 if (!allow_recursive && this->recursive_count != 1) NOT_REACHED();
00119 }
00120
00121 void EndCritical(bool allow_recursive = false)
00122 {
00123 if (!allow_recursive && this->recursive_count != 1) NOT_REACHED();
00124 this->recursive_count--;
00125 DosReleaseMutexSem(mutex);
00126 }
00127
00128 void WaitForSignal()
00129 {
00130 assert(this->recursive_count == 1);
00131 this->EndCritical();
00132 DosWaitEventSem(event, SEM_INDEFINITE_WAIT);
00133 this->BeginCritical();
00134 }
00135
00136 void SendSignal()
00137 {
00138 DosPostEventSem(event);
00139 }
00140 };
00141
00142 ThreadMutex *ThreadMutex::New()
00143 {
00144 return new ThreadMutex_OS2();
00145 }