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 #include "../debug.h"
00015 #include "../core/alloc_func.hpp"
00016 #include <stdlib.h>
00017 #include <windows.h>
00018 #include <process.h>
00019
00023 class ThreadObject_Win32 : public ThreadObject {
00024 private:
00025 HANDLE thread;
00026 uint id;
00027 OTTDThreadFunc proc;
00028 void *param;
00029 bool self_destruct;
00030
00031 public:
00035 ThreadObject_Win32(OTTDThreadFunc proc, void *param, bool self_destruct) :
00036 thread(NULL),
00037 id(0),
00038 proc(proc),
00039 param(param),
00040 self_destruct(self_destruct)
00041 {
00042 this->thread = (HANDLE)_beginthreadex(NULL, 0, &stThreadProc, this, CREATE_SUSPENDED, &this->id);
00043 if (this->thread == NULL) return;
00044 ResumeThread(this->thread);
00045 }
00046
00047 ~ThreadObject_Win32()
00048 {
00049 if (this->thread != NULL) {
00050 CloseHandle(this->thread);
00051 this->thread = NULL;
00052 }
00053 }
00054
00055 bool Exit()
00056 {
00057 assert(GetCurrentThreadId() == this->id);
00058
00059 throw OTTDThreadExitSignal();
00060 }
00061
00062 void Join()
00063 {
00064
00065 assert(GetCurrentThreadId() != this->id);
00066 WaitForSingleObject(this->thread, INFINITE);
00067 }
00068
00069 private:
00074 static uint CALLBACK stThreadProc(void *thr)
00075 {
00076 ((ThreadObject_Win32 *)thr)->ThreadProc();
00077 return 0;
00078 }
00079
00084 void ThreadProc()
00085 {
00086 try {
00087 this->proc(this->param);
00088 } catch (OTTDThreadExitSignal) {
00089 } catch (...) {
00090 NOT_REACHED();
00091 }
00092
00093 if (self_destruct) delete this;
00094 }
00095 };
00096
00097 bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread)
00098 {
00099 ThreadObject *to = new ThreadObject_Win32(proc, param, thread == NULL);
00100 if (thread != NULL) *thread = to;
00101 return true;
00102 }
00103
00107 class ThreadMutex_Win32 : public ThreadMutex {
00108 private:
00109 CRITICAL_SECTION critical_section;
00110 HANDLE event;
00111
00112 public:
00113 ThreadMutex_Win32()
00114 {
00115 InitializeCriticalSection(&this->critical_section);
00116 this->event = CreateEvent(NULL, FALSE, FALSE, NULL);
00117 }
00118
00119 ~ThreadMutex_Win32()
00120 {
00121 DeleteCriticalSection(&this->critical_section);
00122 CloseHandle(this->event);
00123 }
00124
00125 void BeginCritical()
00126 {
00127 EnterCriticalSection(&this->critical_section);
00128 }
00129
00130 void EndCritical()
00131 {
00132 LeaveCriticalSection(&this->critical_section);
00133 }
00134
00135 void WaitForSignal()
00136 {
00137 this->EndCritical();
00138 WaitForSingleObject(this->event, INFINITE);
00139 this->BeginCritical();
00140 }
00141
00142 void SendSignal()
00143 {
00144 SetEvent(this->event);
00145 }
00146 };
00147
00148 ThreadMutex *ThreadMutex::New()
00149 {
00150 return new ThreadMutex_Win32();
00151 }