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) {
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 pthread_mutexattr_t attr;
00101
00102 public:
00103 ThreadMutex_pthread()
00104 {
00105 pthread_mutexattr_init(&this->attr);
00106 pthread_mutexattr_settype(&this->attr, PTHREAD_MUTEX_ERRORCHECK);
00107 pthread_mutex_init(&this->mutex, &this->attr);
00108 pthread_cond_init(&this->condition, NULL);
00109 }
00110
00111 ~ThreadMutex_pthread()
00112 {
00113 int err = pthread_cond_destroy(&this->condition);
00114 assert(err != EBUSY);
00115 err = pthread_mutex_destroy(&this->mutex);
00116 assert(err != EBUSY);
00117 }
00118
00119 void BeginCritical()
00120 {
00121 int err = pthread_mutex_lock(&this->mutex);
00122 assert(err == 0);
00123 }
00124
00125 void EndCritical()
00126 {
00127 int err = pthread_mutex_unlock(&this->mutex);
00128 assert(err == 0);
00129 }
00130
00131 void WaitForSignal()
00132 {
00133 int err = pthread_cond_wait(&this->condition, &this->mutex);
00134 assert(err == 0);
00135 }
00136
00137 void SendSignal()
00138 {
00139 int err = pthread_cond_signal(&this->condition);
00140 assert(err == 0);
00141 }
00142 };
00143
00144 ThreadMutex *ThreadMutex::New()
00145 {
00146 return new ThreadMutex_pthread();
00147 }