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

ArMutex_WIN.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 "ariaOSDef.h"
00028 #include "ArMutex.h"
00029 #include "ArLog.h"
00030 
00031 
00032 ArMutex::ArMutex() :
00033   myFailedInit(false),
00034   myMutex()
00035 {
00036   myLog = false;
00037   myLogName = "";
00038   myMutex=CreateMutex(0, true, 0);
00039   if (!myMutex)
00040   {
00041     myFailedInit=true;
00042     ArLog::logNoLock(ArLog::Terse, "ArMutex::ArMutex: Failed to initialize mutex %s", myLogName.c_str());
00043   }
00044   else
00045     unlock();
00046 
00047   myStrMap[STATUS_FAILED_INIT]="Failed to initialize";
00048   myStrMap[STATUS_FAILED]="General failure";
00049   myStrMap[STATUS_ALREADY_LOCKED]="Mutex already locked";
00050 }
00051 
00052 ArMutex::~ArMutex()
00053 {
00054   if (!myFailedInit && !CloseHandle(myMutex))
00055     ArLog::logNoLock(ArLog::Terse, "ArMutex::~ArMutex: Failed to destroy mutex.");
00056 }
00057 
00058 int ArMutex::lock()
00059 {
00060   DWORD ret;
00061 
00062   if (myLog)
00063     ArLog::log(ArLog::Terse, "Locking %s", myLogName.c_str());
00064   if (myFailedInit)
00065   {
00066     ArLog::logNoLock(ArLog::Terse, "ArMutex::lock: Initialization of mutex %s failed, failed lock", myLogName.c_str());
00067     return(STATUS_FAILED_INIT);
00068   }
00069 
00070   ret=WaitForSingleObject(myMutex, INFINITE);
00071   if (ret == WAIT_ABANDONED)
00072   {
00073     ArLog::logNoLock(ArLog::Terse, "ArMutex::lock: Tried to lock a mutex %s which was locked by a different thread and never unlocked before that thread exited. This is a recoverable error", myLogName.c_str());
00074     return(lock());
00075   }
00076   else if (ret == WAIT_OBJECT_0)
00077     return(0);
00078   else
00079   {
00080     ArLog::logNoLock(ArLog::Terse, "ArMutex::lock: Failed to lock %s due to an unknown error", myLogName.c_str());
00081     return(STATUS_FAILED);
00082   }
00083 
00084   return(0);
00085 }
00086 
00087 int ArMutex::tryLock()
00088 {
00089   DWORD ret;
00090 
00091   if (myFailedInit)
00092   {
00093     ArLog::logNoLock(ArLog::Terse, "ArMutex::lock: Initialization of mutex %s failed, failed lock", myLogName.c_str());
00094     return(STATUS_FAILED_INIT);
00095   }
00096 
00097   // Attempt to wait as little as posesible
00098   ret=WaitForSingleObject(myMutex, 1);
00099   if (ret == WAIT_ABANDONED)
00100   {
00101     ArLog::logNoLock(ArLog::Terse, "ArMutex::lock: Tried to lock mutex %s nwhich was locked by a different thread and never unlocked before that thread exited. This is a recoverable error", myLogName.c_str());
00102     return(lock());
00103   }
00104   else if (ret == WAIT_TIMEOUT)
00105   {
00106     ArLog::logNoLock(ArLog::Terse, "ArMutex::tryLock: Could not lock mutex %s because it is already locked", myLogName.c_str());
00107     return(STATUS_ALREADY_LOCKED);
00108   }
00109   else if (ret == WAIT_OBJECT_0)
00110     return(0);
00111   else
00112   {
00113     ArLog::logNoLock(ArLog::Terse, "ArMutex::lock: Failed to lock %s due to an unknown error", myLogName.c_str());
00114     return(STATUS_FAILED);
00115   }
00116 
00117   return(0);
00118 }
00119 
00120 int ArMutex::unlock()
00121 {
00122   if (myLog)
00123     ArLog::log(ArLog::Terse, "Unlocking %s", myLogName.c_str());
00124   if (myFailedInit)
00125   {
00126     ArLog::logNoLock(ArLog::Terse, "ArMutex::unlock: Initialization of mutex %s failed, failed unlock", myLogName.c_str());
00127     return(STATUS_FAILED_INIT);
00128   }
00129 
00130   if (!ReleaseMutex(myMutex))
00131   {
00132     ArLog::logNoLock(ArLog::Terse, "ArMutex::unlock: Failed to unlock %s due to an unknown error", myLogName.c_str());
00133     return(STATUS_FAILED);
00134   }
00135 
00136   return(0);
00137 }
00138 
00139 AREXPORT const char * ArMutex::getError(int messageNumber) const
00140 {
00141   ArStrMap::const_iterator it;
00142   if ((it = myStrMap.find(messageNumber)) != myStrMap.end())
00143     return (*it).second.c_str();
00144   else
00145     return NULL;
00146 
00147 }

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