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

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

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