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

ArMutex_LIN.cpp

00001 /*
00002 MobileRobots Advanced Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004, 2005 ActivMedia Robotics LLC
00004 Copyright (C) 2006, 2007 MobileRobots Inc.
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 MobileRobots for information about a commercial version of ARIA at 
00022 robots@mobilerobots.com or 
00023 MobileRobots Inc, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
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>     // for getpid()
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 }

Generated on Tue Feb 20 10:51:40 2007 for Aria by  doxygen 1.4.0