thread_win32.cpp
Go to the documentation of this file.00001
00002
00005 #include "stdafx.h"
00006 #include "thread.h"
00007 #include "debug.h"
00008 #include "core/alloc_func.hpp"
00009 #include <stdlib.h>
00010 #include <windows.h>
00011 #include <process.h>
00012
00016 class ThreadObject_Win32 : public ThreadObject {
00017 private:
00018 HANDLE thread;
00019 uint id;
00020 OTTDThreadFunc proc;
00021 void *param;
00022 bool self_destruct;
00023
00024 public:
00028 ThreadObject_Win32(OTTDThreadFunc proc, void *param, bool self_destruct) :
00029 thread(NULL),
00030 id(0),
00031 proc(proc),
00032 param(param),
00033 self_destruct(self_destruct)
00034 {
00035 this->thread = (HANDLE)_beginthreadex(NULL, 0, &stThreadProc, this, CREATE_SUSPENDED, &this->id);
00036 if (this->thread == NULL) return;
00037 ResumeThread(this->thread);
00038 }
00039
00040 ~ThreadObject_Win32()
00041 {
00042 if (this->thread != NULL) {
00043 CloseHandle(this->thread);
00044 this->thread = NULL;
00045 }
00046 }
00047
00048 bool Exit()
00049 {
00050 assert(GetCurrentThreadId() == this->id);
00051
00052 throw OTTDThreadExitSignal();
00053 }
00054
00055 void Join()
00056 {
00057
00058 assert(GetCurrentThreadId() != this->id);
00059 WaitForSingleObject(this->thread, INFINITE);
00060 }
00061
00062 private:
00067 static uint CALLBACK stThreadProc(void *thr)
00068 {
00069 ((ThreadObject_Win32 *)thr)->ThreadProc();
00070 return 0;
00071 }
00072
00077 void ThreadProc()
00078 {
00079 try {
00080 this->proc(this->param);
00081 } catch (OTTDThreadExitSignal) {
00082 } catch (...) {
00083 NOT_REACHED();
00084 }
00085
00086 if (self_destruct) delete this;
00087 }
00088 };
00089
00090 bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread)
00091 {
00092 ThreadObject *to = new ThreadObject_Win32(proc, param, thread == NULL);
00093 if (thread != NULL) *thread = to;
00094 return true;
00095 }
00096
00100 class ThreadMutex_Win32 : public ThreadMutex {
00101 private:
00102 CRITICAL_SECTION critical_section;
00103
00104 public:
00105 ThreadMutex_Win32()
00106 {
00107 InitializeCriticalSection(&this->critical_section);
00108 }
00109
00110 ~ThreadMutex_Win32()
00111 {
00112 DeleteCriticalSection(&this->critical_section);
00113 }
00114
00115 void BeginCritical()
00116 {
00117 EnterCriticalSection(&this->critical_section);
00118 }
00119
00120 void EndCritical()
00121 {
00122 LeaveCriticalSection(&this->critical_section);
00123 }
00124 };
00125
00126 ThreadMutex *ThreadMutex::New()
00127 {
00128 return new ThreadMutex_Win32();
00129 }