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

ArCondition_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 #include <errno.h>
00028 #include <time.h>
00029 #include <math.h>
00030 #include "ariaOSDef.h"
00031 #include "ArCondition.h"
00032 #include "ArLog.h"
00033 #include <sys/time.h>
00034 
00035 ArStrMap ArCondition::ourStrMap;
00036 
00037 
00038 AREXPORT ArCondition::ArCondition() :
00039   myFailedInit(false),
00040   myCond(),
00041   myMutex()
00042 {
00043   pthread_condattr_t attr;
00044 
00045   pthread_condattr_init(&attr);
00046   if (pthread_cond_init(&myCond, &attr) != 0)
00047   {
00048     ArLog::log(ArLog::Terse, "ArCondition::ArCondition: Unknown error trying to create the condition.");
00049     myFailedInit=true;
00050   }
00051 
00052   pthread_condattr_destroy(&attr);
00053 
00054   ourStrMap[STATUS_FAILED]="General failure";
00055   ourStrMap[STATUS_FAILED_DESTROY]=
00056   "Another thread is waiting on this condition so it can not be destroyed";
00057   ourStrMap[STATUS_FAILED_INIT] =
00058   "Failed to initialize thread. Requested action is imposesible";
00059   ourStrMap[STATUS_MUTEX_FAILED_INIT]="The underlying mutex failed to init";
00060   ourStrMap[STATUS_MUTEX_FAILED]="The underlying mutex failed in some fashion";
00061 }
00062 
00063 AREXPORT ArCondition::~ArCondition()
00064 {
00065   int ret;
00066 
00067   ret=pthread_cond_destroy(&myCond);
00068   if (ret == EBUSY)
00069     ArLog::log(ArLog::Terse, "ArCondition::~ArCondition: Trying to destroy a condition that another thread is waiting on.");
00070   else if (ret != 0)
00071     ArLog::log(ArLog::Terse, "ArCondition::~ArCondition: Unknown error while trying to destroy the condition.");
00072 }
00073 
00074 AREXPORT int ArCondition::signal()
00075 {
00076   if (myFailedInit)
00077   {
00078     ArLog::log(ArLog::Terse, "ArCondition::signal: Initialization of condition failed, failed to signal");
00079     return(STATUS_FAILED_INIT);
00080   }
00081 
00082   if (pthread_cond_signal(&myCond) != 0)
00083   {
00084     ArLog::log(ArLog::Terse, "ArCondition::signal: Unknown error while trying to signal the condition.");
00085     return(STATUS_FAILED);
00086   }
00087 
00088   return(0);
00089 }
00090 
00091 AREXPORT int ArCondition::broadcast()
00092 {
00093   if (myFailedInit)
00094   {
00095     ArLog::log(ArLog::Terse, "ArCondition::broadcast: Initialization of condition failed, failed to broadcast");
00096     return(STATUS_FAILED_INIT);
00097   }
00098 
00099   if (pthread_cond_broadcast(&myCond) != 0)
00100   {
00101     ArLog::log(ArLog::Terse, "ArCondition::broadcast: Unknown error while trying to broadcast the condition.");
00102     return(STATUS_FAILED);
00103   }
00104 
00105   return(0);
00106 }
00107 
00108 AREXPORT int ArCondition::wait()
00109 {
00110   int ret;
00111 
00112   if (myFailedInit)
00113   {
00114     ArLog::log(ArLog::Terse, "ArCondition::wait: Initialization of condition failed, failed to wait");
00115     return(STATUS_FAILED_INIT);
00116   }
00117 
00118   ret=myMutex.lock();
00119   if (ret != 0)
00120   {
00121     if (ret == ArMutex::STATUS_FAILED_INIT)
00122       return(STATUS_MUTEX_FAILED_INIT);
00123     else
00124       return(STATUS_MUTEX_FAILED);
00125   }
00126 
00127   ret=pthread_cond_wait(&myCond, &myMutex.getMutex());
00128   if (ret != 0)
00129   {
00130     if (ret == EINTR)
00131       return(STATUS_WAIT_INTR);
00132     else
00133     {
00134       ArLog::log(ArLog::Terse, "ArCondition::wait: Unknown error while trying to wait on the condition.");
00135       return(STATUS_FAILED);
00136     }
00137   }
00138 
00139   ret=myMutex.unlock();
00140   if (ret != 0)
00141   {
00142     if (ret == ArMutex::STATUS_FAILED_INIT)
00143       return(STATUS_MUTEX_FAILED_INIT);
00144     else
00145       return(STATUS_MUTEX_FAILED);
00146   }
00147 
00148   return(0);
00149 }
00150 
00151 AREXPORT int ArCondition::timedWait(unsigned int msecs)
00152 {
00153   int ret;
00154   int retUnlock;
00155   struct timespec spec;
00156   struct timeval  tp;
00157 
00158   if (myFailedInit)
00159   {
00160     ArLog::log(ArLog::Terse, "ArCondition::wait: Initialization of condition failed, failed to wait");
00161     return(STATUS_FAILED_INIT);
00162   }
00163 
00164   ret=myMutex.lock();
00165   if (ret != 0)
00166   {
00167     if (ret == ArMutex::STATUS_FAILED_INIT)
00168       return(STATUS_MUTEX_FAILED_INIT);
00169     else
00170       return(STATUS_MUTEX_FAILED);
00171   }
00172 
00173   gettimeofday(&tp, NULL);
00174   // convert time of day to pthread time structure
00175   spec.tv_sec = tp.tv_sec;
00176   spec.tv_nsec = tp.tv_usec * 1000;
00177 
00178   // add on time specified by msecs
00179   spec.tv_sec += (long int)rint(((float)msecs)/1000.0);
00180   // 1 millisecond = 1000 micro seconds = 1000000 nanoseconds
00181   spec.tv_nsec += (long int)( ( msecs % 1000 ) * 1000000);
00182 //   printf("input millisecond=%d :: sec=%ld nsec=%ld curtime=%ld %ld\n", msecs, spec.tv_sec, spec.tv_nsec, tp.tv_sec, tp.tv_usec * 1000);
00183 
00184   ret=pthread_cond_timedwait(&myCond, &myMutex.getMutex(), &spec);
00185 
00186   // must unlock the mutex, even if we fail, since we reacquire lock
00187   // after timedwait times out
00188   retUnlock=myMutex.unlock();
00189   
00190   if (ret != 0)
00191   {
00192     if (ret == EINTR)
00193       return(STATUS_WAIT_INTR);
00194     else if (ret == ETIMEDOUT)
00195       return(STATUS_WAIT_TIMEDOUT);
00196     else
00197     {
00198       ArLog::log(ArLog::Terse, "ArCondition::timedWait: Unknown error while trying to wait on the condition.");
00199       return(STATUS_FAILED);
00200     }
00201   }
00202 
00203   if (retUnlock != 0)
00204   {
00205     if (retUnlock == ArMutex::STATUS_FAILED_INIT)
00206       return(STATUS_MUTEX_FAILED_INIT);
00207     else
00208       return(STATUS_MUTEX_FAILED);
00209   }
00210 
00211   return(0);
00212 }
00213 
00214 AREXPORT const char * ArCondition::getError(int messageNumber) const
00215 {
00216   ArStrMap::const_iterator it;
00217   if ((it = ourStrMap.find(messageNumber)) != ourStrMap.end())
00218     return (*it).second.c_str();
00219   else
00220     return NULL;
00221 }

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