thread_pthread.cpp
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 <pthread.h>
00015 #include <errno.h>
00016
00020 class ThreadObject_pthread : public ThreadObject {
00021 private:
00022 pthread_t thread;
00023 OTTDThreadFunc proc;
00024 void *param;
00025 bool self_destruct;
00026
00027 public:
00031 ThreadObject_pthread(OTTDThreadFunc proc, void *param, bool self_destruct) :
00032 thread(0),
00033 proc(proc),
00034 param(param),
00035 self_destruct(self_destruct)
00036 {
00037 pthread_create(&this->thread, NULL, &stThreadProc, this);
00038 }
00039
00040 bool Exit()
00041 {
00042 assert(pthread_self() == this->thread);
00043
00044 throw OTTDThreadExitSignal();
00045 }
00046
00047 void Join()
00048 {
00049
00050 assert(pthread_self() != this->thread);
00051 pthread_join(this->thread, NULL);
00052 this->thread = 0;
00053 }
00054 private:
00059 static void *stThreadProc(void *thr)
00060 {
00061 ((ThreadObject_pthread *)thr)->ThreadProc();
00062 pthread_exit(NULL);
00063 }
00064
00069 void ThreadProc()
00070 {
00071
00072 try {
00073 this->proc(this->param);
00074 } catch (OTTDThreadExitSignal e) {
00075 } catch (...) {
00076 NOT_REACHED();
00077 }
00078
00079 if (self_destruct) {
00080 pthread_detach(pthread_self());
00081 delete this;
00082 }
00083 }
00084 };
00085
00086 bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread)
00087 {
00088 ThreadObject *to = new ThreadObject_pthread(proc, param, thread == NULL);
00089 if (thread != NULL) *thread = to;
00090 return true;
00091 }
00092
00096 class ThreadMutex_pthread : public ThreadMutex {
00097 private:
00098 pthread_mutex_t mutex;
00099 pthread_cond_t condition;
00100
00101 public:
00102 ThreadMutex_pthread()
00103 {
00104 pthread_mutex_init(&this->mutex, NULL);
00105 pthread_cond_init(&this->condition, NULL);
00106 }
00107
00108 ~ThreadMutex_pthread()
00109 {
00110 int err = pthread_cond_destroy(&this->condition);
00111 assert(err != EBUSY);
00112 err = pthread_mutex_destroy(&this->mutex);
00113 assert(err != EBUSY);
00114 }
00115
00116 void BeginCritical()
00117 {
00118 pthread_mutex_lock(&this->mutex);
00119 }
00120
00121 void EndCritical()
00122 {
00123 pthread_mutex_unlock(&this->mutex);
00124 }
00125
00126 void WaitForSignal()
00127 {
00128 pthread_cond_wait(&this->condition, &this->mutex);
00129 }
00130
00131 void SendSignal()
00132 {
00133 pthread_cond_signal(&this->condition);
00134 }
00135 };
00136
00137 ThreadMutex *ThreadMutex::New()
00138 {
00139 return new ThreadMutex_pthread();
00140 }