00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "ArExport.h"
00027
00028
00029
00030 #include <errno.h>
00031 #include <list>
00032 #include <sched.h>
00033 #include <sys/types.h>
00034 #include <unistd.h>
00035 #include "ariaOSDef.h"
00036 #include "ArThread.h"
00037 #include "ArLog.h"
00038 #include "ArSignalHandler.h"
00039
00040
00041 static void * run(void *arg)
00042 {
00043 ArThread *t=(ArThread*)arg;
00044 void *ret=NULL;
00045
00046 if (t->getBlockAllSignals())
00047 ArSignalHandler::blockCommonThisThread();
00048
00049 if (dynamic_cast<ArRetFunctor<void*>*>(t->getFunc()))
00050 ret=((ArRetFunctor<void*>*)t->getFunc())->invokeR();
00051 else
00052 t->getFunc()->invoke();
00053
00054 return(ret);
00055 }
00056
00057
00065 void ArThread::init()
00066 {
00067 ArThread *main;
00068 ThreadType pt;
00069
00070 pt=pthread_self();
00071
00072 ourThreadsMutex.lock();
00073 if (ourThreads.size())
00074 {
00075 ourThreadsMutex.unlock();
00076 return;
00077 }
00078 main=new ArThread;
00079 main->myJoinable=true;
00080 main->myRunning=true;
00081 main->myThread=pt;
00082 ourThreads.insert(MapType::value_type(pt, main));
00083 ourThreadsMutex.unlock();
00084 }
00085
00094 ArThread * ArThread::self()
00095 {
00096 ThreadType pt;
00097 MapType::iterator iter;
00098
00099 ourThreadsMutex.lock();
00100 pt=pthread_self();
00101 iter=ourThreads.find(pt);
00102 ourThreadsMutex.unlock();
00103
00104 if (iter != ourThreads.end())
00105 return((*iter).second);
00106 else
00107 return(NULL);
00108 }
00109
00110 void ArThread::cancelAll()
00111 {
00112 MapType::iterator iter;
00113
00114 ourThreadsMutex.lock();
00115 for (iter=ourThreads.begin(); iter != ourThreads.end(); ++iter)
00116 {
00117 pthread_cancel((*iter).first);
00118 (*iter).second->stopRunning();
00119 }
00120 ourThreads.clear();
00121 ourThreadsMutex.unlock();
00122 }
00123
00124 int ArThread::create(ArFunctor *func, bool joinable, bool lowerPriority)
00125 {
00126 int ret;
00127 pthread_attr_t attr;
00128
00129 pthread_attr_init(&attr);
00130 if (joinable)
00131 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
00132 else
00133 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
00134 myJoinable=joinable;
00135 myFunc=func;
00136 myRunning=true;
00137 if (myBlockAllSignals)
00138 {
00139 ArSignalHandler::blockCommonThisThread();
00140 }
00141 if ((ret=pthread_create(&myThread, &attr, &run, this)) != 0)
00142 {
00143 pthread_attr_destroy(&attr);
00144 if (ret == EAGAIN)
00145 {
00146 ArLog::log(ArLog::Terse, "ArThread::create: Error in create, not enough system resources in pthread_create()");
00147 return(STATUS_NORESOURCE);
00148 }
00149 else
00150 {
00151 ArLog::log(ArLog::Terse, "ArThread::create: Unknown error in create.");
00152 return(STATUS_FAILED);
00153 }
00154 }
00155 else
00156 {
00157 if (myName.size() == 0)
00158 ArLog::log(ourLogLevel, "Created anonymous thread with ID %d",
00159 myThread);
00160 else
00161 ArLog::log(ourLogLevel, "Created %s thread with ID %d", myName.c_str(),
00162 myThread);
00163 ourThreadsMutex.lock();
00164 ourThreads.insert(MapType::value_type(myThread, this));
00165 ourThreadsMutex.unlock();
00166 pthread_attr_destroy(&attr);
00167 return(0);
00168 }
00169 }
00170
00171 int ArThread::doJoin(void **iret)
00172 {
00173 int ret;
00174 if ((ret=pthread_join(myThread, iret)) != 0)
00175 {
00176 if (ret == ESRCH)
00177 {
00178 ArLog::log(ArLog::Terse, "ArThread::join: Error in join: No such thread found");
00179 return(STATUS_NO_SUCH_THREAD);
00180 }
00181 else if (ret == EINVAL)
00182 {
00183 ArLog::log(ArLog::Terse, "ArThread::join: Error in join: Thread is detached or another thread is waiting");
00184 return(STATUS_INVALID);
00185 }
00186 else if (ret == EDEADLK)
00187 {
00188 ArLog::log(ArLog::Terse, "ArThread::join: Error in join: Trying to join on self");
00189 return(STATUS_JOIN_SELF);
00190 }
00191 }
00192
00193 return(0);
00194 }
00195
00196 int ArThread::detach()
00197 {
00198 int ret;
00199
00200 if ((ret=pthread_detach(myThread)) != 0)
00201 {
00202 if (ret == ESRCH)
00203 {
00204 ArLog::log(ArLog::Terse, "ArThread::detach: Error in detach: No such thread found");
00205 return(STATUS_NO_SUCH_THREAD);
00206 }
00207 else if (ret == EINVAL)
00208 {
00209 ArLog::log(ArLog::Terse, "ArThread::detach: Error in detach: ArThread is already detached");
00210 return(STATUS_ALREADY_DETATCHED);
00211 }
00212 }
00213
00214 myJoinable=false;
00215 return(0);
00216 }
00217
00218 void ArThread::cancel()
00219 {
00220 ourThreadsMutex.lock();
00221 ourThreads.erase(myThread);
00222 ourThreadsMutex.unlock();
00223 pthread_cancel(myThread);
00224 }
00225
00226 void ArThread::yieldProcessor()
00227 {
00228 sched_yield();
00229 }
00230
00231 AREXPORT void ArThread::threadStarted(void)
00232 {
00233 myPID = getpid();
00234 if (myName.size() == 0)
00235 ArLog::log(ourLogLevel, "Anonymous thread (%d) is running with pid %d",
00236 myThread, myPID);
00237 else
00238 ArLog::log(ourLogLevel, "Thread %s (%d) is running with pid %d",
00239 myName.c_str(), myThread, myPID);
00240 }
00241
00242
00243 AREXPORT void ArThread::logThreadInfo(void)
00244 {
00245 if (myName.size() == 0)
00246 ArLog::log(ourLogLevel, "Anonymous thread (%d) is running with pid %d",
00247 myThread, myPID);
00248 else
00249 ArLog::log(ourLogLevel, "Thread %s (%d) is running with pid %d",
00250 myName.c_str(), myThread, myPID);
00251 }