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 "ariaOSDef.h"
00030 #include "ArMutex.h"
00031 #include "ArLog.h"
00032 #include "ArThread.h"
00033
00034 #include <sys/types.h>
00035 #include <unistd.h>
00036
00037 ArMutex::ArMutex() :
00038 myFailedInit(false),
00039 myMutex()
00040 {
00041 myLog = false;
00042 if (pthread_mutex_init(&myMutex, 0) < 0)
00043 {
00044 myFailedInit=true;
00045 ArLog::logNoLock(ArLog::Terse, "ArMutex::ArMutex: Failed to initialize mutex");
00046 }
00047 else
00048 unlock();
00049
00050 myStrMap[STATUS_FAILED_INIT]="Failed to initialize";
00051 myStrMap[STATUS_FAILED]="General failure";
00052 myStrMap[STATUS_ALREADY_LOCKED]="Mutex already locked";
00053 }
00054
00055 ArMutex::~ArMutex()
00056 {
00057 if (!myFailedInit && (pthread_mutex_destroy(&myMutex) < 0))
00058 {
00059 if (errno == EBUSY)
00060 ArLog::logNoLock(ArLog::Terse, "ArMutex::~ArMutex: Failed to destroy mutex. A thread is currently blocked waiting for this mutex.");
00061 else
00062 ArLog::logNoLock(ArLog::Terse, "ArMutex::~ArMutex: Failed to destroy mutex. Unknown error.");
00063 }
00064 }
00065
00072 int ArMutex::lock()
00073 {
00074 if (myLog && ArThread::self() != NULL)
00075 ArLog::log(ArLog::Terse, "Locking %s from thread %s %d pid %d",
00076 myLogName.c_str(),
00077 ArThread::self()->getThreadName(),
00078 *(ArThread::self()->getThread()), getpid());
00079 else if (myLog)
00080 ArLog::log(ArLog::Terse,
00081 "Locking %s probably from pid %d", getpid());
00082 if (myFailedInit)
00083 {
00084 ArLog::logNoLock(ArLog::Terse, "ArMutex::lock: Initialization of mutex failed, failed lock");
00085 return(STATUS_FAILED_INIT);
00086 }
00087
00088 if (pthread_mutex_lock(&myMutex) < 0)
00089 {
00090 if (errno == EDEADLK)
00091 {
00092 ArLog::logNoLock(ArLog::Terse, "ArMutex::lock: Trying to lock a mutex which is already locked by this thread");
00093 return(STATUS_ALREADY_LOCKED);
00094 }
00095 else
00096 {
00097 ArLog::logNoLock(ArLog::Terse, "ArMutex::lock: Failed to lock due to an unknown error");
00098 return(STATUS_FAILED);
00099 }
00100 }
00101
00102 return(0);
00103 }
00104
00111 int ArMutex::tryLock()
00112 {
00113 if (myFailedInit)
00114 {
00115 ArLog::logNoLock(ArLog::Terse, "ArMutex::tryLock: Initialization of mutex failed, failed trylock");
00116 return(STATUS_FAILED_INIT);
00117 }
00118
00119 if (pthread_mutex_trylock(&myMutex) < 0)
00120 {
00121 if (errno == EBUSY)
00122 {
00123 ArLog::logNoLock(ArLog::Terse, "ArMutex::tryLock: Could not lock mutex because it is already locked");
00124 return(STATUS_ALREADY_LOCKED);
00125 }
00126 else
00127 {
00128 ArLog::logNoLock(ArLog::Terse, "ArMutex::trylock: Failed to trylock due to an unknown error");
00129 return(STATUS_FAILED);
00130 }
00131 }
00132
00133 return(0);
00134 }
00135
00136 int ArMutex::unlock()
00137 {
00138 if (myLog && ArThread::self() != NULL)
00139 ArLog::log(ArLog::Terse, "Unlocking %s from thread %s %d pid %d",
00140 myLogName.c_str(),
00141 ArThread::self()->getThreadName(),
00142 *(ArThread::self()->getThread()), getpid());
00143 else if (myLog)
00144 ArLog::log(ArLog::Terse,
00145 "Unlocking %s probably from pid %d", getpid());
00146 if (myFailedInit)
00147 {
00148 ArLog::logNoLock(ArLog::Terse, "ArMutex::unlock: Initialization of mutex failed, failed unlock");
00149 return(STATUS_FAILED_INIT);
00150 }
00151
00152 if (pthread_mutex_unlock(&myMutex) < 0)
00153 {
00154 if (errno == EPERM)
00155 {
00156 ArLog::logNoLock(ArLog::Terse, "ArMutex::unlock: Trying to unlock a mutex which this thread does not own");
00157 return(STATUS_ALREADY_LOCKED);
00158 }
00159 else
00160 {
00161 ArLog::logNoLock(ArLog::Terse, "ArMutex::unlock: Failed to unlock due to an unknown error");
00162 return(STATUS_FAILED);
00163 }
00164 }
00165
00166 return(0);
00167 }
00168
00169 const char *ArMutex::getError(int messageNumber) const
00170 {
00171 ArStrMap::const_iterator it;
00172 if ((it = myStrMap.find(messageNumber)) != myStrMap.end())
00173 return (*it).second.c_str();
00174 else
00175 return NULL;
00176 }