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