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

ArMutex_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 "ariaOSDef.h"
00030 #include "ArMutex.h"
00031 #include "ArLog.h"
00032 #include "ArThread.h"
00033 
00034 #include <sys/types.h>
00035 #include <unistd.h>     // for getpid()
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 }

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