thread_win32.cpp

Go to the documentation of this file.
00001 /* $Id: thread_win32.cpp 15159 2009-01-20 03:44:43Z rubidium $ */
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   /* virtual */ ~ThreadObject_Win32()
00041   {
00042     if (this->thread != NULL) {
00043       CloseHandle(this->thread);
00044       this->thread = NULL;
00045     }
00046   }
00047 
00048   /* virtual */ bool Exit()
00049   {
00050     assert(GetCurrentThreadId() == this->id);
00051     /* For now we terminate by throwing an error, gives much cleaner cleanup */
00052     throw OTTDThreadExitSignal();
00053   }
00054 
00055   /* virtual */ void Join()
00056   {
00057     /* You cannot join yourself */
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 /* static */ 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   /* virtual */ ~ThreadMutex_Win32()
00111   {
00112     DeleteCriticalSection(&this->critical_section);
00113   }
00114 
00115   /* virtual */ void BeginCritical()
00116   {
00117     EnterCriticalSection(&this->critical_section);
00118   }
00119 
00120   /* virtual */ void EndCritical()
00121   {
00122     LeaveCriticalSection(&this->critical_section);
00123   }
00124 };
00125 
00126 /* static */ ThreadMutex *ThreadMutex::New()
00127 {
00128   return new ThreadMutex_Win32();
00129 }

Generated on Wed Apr 1 14:38:11 2009 for OpenTTD by  doxygen 1.5.6