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