# thread_pthread.cpp

Go to the documentation of this file.

    00001 /* $Id: thread_pthread.cpp 15663 2009-03-10 11:12:03Z rubidium $ */
    00002
    00005 #include "stdafx.h"
    00006 #include "thread.h"
    00007 #include <pthread.h>
    00008
    00012 class ThreadObject_pthread : public ThreadObject {
    00013 private:
    00014   pthread_t thread;
    00015   OTTDThreadFunc proc;
    00016   void *param;
    00017   bool self_destruct;
    00018
    00019 public:
    00023   ThreadObject_pthread(OTTDThreadFunc proc, void *param, bool self_destruct) :
    00024     thread(0),
    00025     proc(proc),
    00026     param(param),
    00027     self_destruct(self_destruct)
    00028   {
    00029     pthread_create(&this->thread, NULL, &stThreadProc, this);
    00030   }
    00031
    00032   /* virtual */ bool Exit()
    00033   {
    00034     assert(pthread_self() == this->thread);
    00035     /* For now we terminate by throwing an error, gives much cleaner cleanup */
    00036     throw OTTDThreadExitSignal();
    00037   }
    00038
    00039   /* virtual */ void Join()
    00040   {
    00041     /* You cannot join yourself */
    00042     assert(pthread_self() != this->thread);
    00043     pthread_join(this->thread, NULL);
    00044     this->thread = 0;
    00045   }
    00046 private:
    00051   static void *stThreadProc(void *thr)
    00052   {
    00053     ((ThreadObject_pthread *)thr)->ThreadProc();
    00054     pthread_exit(NULL);
    00055   }
    00056
    00061   void ThreadProc()
    00062   {
    00063     /* Call the proc of the creator to continue this thread */
    00064     try {
    00065       this->proc(this->param);
    00066     } catch (OTTDThreadExitSignal e) {
    00067     } catch (...) {
    00068       NOT_REACHED();
    00069     }
    00070
    00071     if (self_destruct) {
    00072       pthread_detach(pthread_self());
    00073       delete this;
    00074     }
    00075   }
    00076 };
    00077
    00078 /* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread)
    00079 {
    00080   ThreadObject *to = new ThreadObject_pthread(proc, param, thread == NULL);
    00081   if (thread != NULL) *thread = to;
    00082   return true;
    00083 }
    00084
    00088 class ThreadMutex_pthread : public ThreadMutex {
    00089 private:
    00090   pthread_mutex_t mutex;
    00091
    00092 public:
    00093   ThreadMutex_pthread()
    00094   {
    00095     pthread_mutex_init(&this->mutex, NULL);
    00096   }
    00097
    00098   /* virtual */ ~ThreadMutex_pthread()
    00099   {
    00100     pthread_mutex_destroy(&this->mutex);
    00101   }
    00102
    00103   /* virtual */ void BeginCritical()
    00104   {
    00105     pthread_mutex_lock(&this->mutex);
    00106   }
    00107
    00108   /* virtual */ void EndCritical()
    00109   {
    00110     pthread_mutex_unlock(&this->mutex);
    00111   }
    00112 };
    00113
    00114 /* static */ ThreadMutex *ThreadMutex::New()
    00115 {
    00116   return new ThreadMutex_pthread();
    00117 }