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

ArThread_LIN.cpp

00001 /*
00002 MobileRobots Advanced Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004, 2005 ActivMedia Robotics LLC
00004 Copyright (C) 2006, 2007 MobileRobots Inc.
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 MobileRobots for information about a commercial version of ARIA at 
00022 robots@mobilerobots.com or 
00023 MobileRobots Inc, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
00024 */
00025 
00026 #include "ArExport.h"
00027 // ArThread.cc -- Thread classes
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 }

Generated on Tue Feb 20 10:51:41 2007 for Aria by  doxygen 1.4.0