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 #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
00175 spec.tv_sec = tp.tv_sec;
00176 spec.tv_nsec = tp.tv_usec * 1000;
00177
00178
00179 spec.tv_sec += (long int)rint(((float)msecs)/1000.0);
00180
00181 spec.tv_nsec += (long int)( ( msecs % 1000 ) * 1000000);
00182
00183
00184 ret=pthread_cond_timedwait(&myCond, &myMutex.getMutex(), &spec);
00185
00186
00187
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 }