Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

ArThread_LIN.cpp

00001 /*
00002 ActivMedia Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004,2005 ActivMedia Robotics, LLC
00004 
00005 
00006      This program is free software; you can redistribute it and/or modify
00007      it under the terms of the GNU General Public License as published by
00008      the Free Software Foundation; either version 2 of the License, or
00009      (at your option) any later version.
00010 
00011      This program is distributed in the hope that it will be useful,
00012      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014      GNU General Public License for more details.
00015 
00016      You should have received a copy of the GNU General Public License
00017      along with this program; if not, write to the Free Software
00018      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 If you wish to redistribute ARIA under different terms, contact 
00021 ActivMedia Robotics for information about a commercial version of ARIA at 
00022 robots@activmedia.com or 
00023 ActivMedia Robotics, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
00024 
00025 */
00026 
00027 #include "ArExport.h"
00028 // ArThread.cc -- Thread classes
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 }

Generated on Wed Oct 19 12:56:37 2005 for Aria by  doxygen 1.4.0