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

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

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