00001 #include "thread.h"
00002
00003 namespace n2nc {
00004 namespace sync {
00005
00006 std::map<pthread_t,Thread*> Thread::m_runthreads ;
00007 n2nc::sync::Mutex Thread::m_maplock ;
00008
00009 Thread::Thread()
00010 {
00011 this->m_isrunning = false ;
00012 this->m_isstarted = false ;
00013 this->m_iscancelled = false ;
00014 }
00015
00016 int Thread::pre_start(){
00017
00018 std::cerr << "pre_start\n" ;
00019 }
00020
00021 int Thread::run(void *args){
00022 this->m_args = args ;
00023 typedef void*(*my_entry_point_t)(void*);
00024 my_entry_point_t startme = (my_entry_point_t)&Thread::_start ;
00025 pthread_create(&this->m_thread,NULL,startme,this);
00026 }
00027
00028 int Thread::exit_point(){
00029
00030 std::cerr << "exit_point, cancelled ?" << this->m_iscancelled << std::endl ; ;
00031
00032 }
00033
00034
00035 int Thread::terminate(){
00036 if(!this->m_isstarted){ std::cerr << "Thread::terminate(). Not yet started thread" << std::endl ; return -1 ;}
00037 if(!this->m_isrunning){ std::cerr << "Thread::terminate(). Not running thread" << std::endl ; return -1 ;}
00038 if(this->m_isrunning) return pthread_cancel(this->m_thread);
00039 }
00040
00041 int Thread::wait(void **retval){
00042 if(!this->m_isstarted){ std::cerr << "Thread::wait(). Not yet started thread" << std::endl ; return -1 ;}
00043 if(!this->m_isrunning){ std::cerr << "Thread::wait(). Not running thread" << std::endl ; return -1 ;}
00044 return pthread_join(this->m_thread,retval);
00045 }
00046
00047 extern "C"
00048 void* Thread::_start(Thread* caller){
00049 void *retval = NULL ;
00050 try {
00051
00052 caller->m_isstarted = true ;
00053 caller->m_isrunning = true ;
00054 Thread::m_maplock.lock();
00055 Thread::m_runthreads.insert( std::pair<pthread_t,Thread*>(caller->m_thread,caller) );
00056 Thread::m_maplock.unlock();
00057
00058 caller->pre_start();
00059
00060
00061 retval = caller->entry_point();
00062 caller->m_ret_args = retval ;
00063 caller->m_isrunning = false ;
00064
00065
00066 caller->exit_point();
00067
00068 Thread::m_maplock.lock();
00069 Thread::m_runthreads.erase(caller->m_thread );
00070 Thread::m_maplock.unlock();
00071
00072
00073 }
00074 catch(const std::exception& e){
00075 std::cerr << "thread _start exception:" << e.what() << std::endl ;
00076 caller->m_iscancelled = true ;
00077 caller->exit_point();
00078 throw ;
00079 }
00080 catch(...){
00081 std::cerr << "thread cancelled\n" ;
00082 caller->m_iscancelled = true ;
00083 caller->exit_point();
00084 throw ;
00085 }
00086 return retval ;
00087 }
00088
00089 Thread::~Thread(){
00090
00091 }
00092
00093
00094 bool Thread::init(){
00095 Thread *t = new MainThread();
00096 t->m_thread = pthread_self();
00097 Thread::m_runthreads.insert( std::pair<pthread_t,Thread*>(t->m_thread,t) );
00098 }
00099
00100 void Thread::setName(std::string name){
00101 this->m_name = name ;
00102 }
00103
00104 Thread &Thread::getCurrent(){
00105 pthread_t t = pthread_self() ;
00106 std::map<pthread_t,Thread*>::iterator it ;
00107 it = Thread::m_runthreads.find(t);
00108 if(it == Thread::m_runthreads.end() ){
00109 std::cerr << "WARNING: Not found.main thread is not initialized: perhaps have you Thread::init() ?" << std::endl ;
00110 std::cerr << "i guess this caller is main thread, so do it for you!" << std::endl ;
00111 Thread::init();
00112 return Thread::getCurrent();
00113
00114 }
00115 Thread &tref = *(it->second) ;
00116 return tref;
00117 }
00118
00119 std::string Thread::toString(){
00120 return this->m_name ;
00121 }
00122
00123 void* Thread::getRetVal(){
00124 if(this->m_isrunning){ std::cerr << "Thread::getRetVal(). Still running thread" << std::endl ; return NULL ;}
00125 return this->m_ret_args ;
00126 }
00127
00128
00129 }
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156