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