Vault
4.1
|
00001 /* 00002 Copyright c1997-2014 Trygve Isaacson. All rights reserved. 00003 This file is part of the Code Vault version 4.1 00004 http://www.bombaydigital.com/ 00005 License: MIT. See LICENSE.md in the Vault top level directory. 00006 */ 00007 00010 #include "vmutexlocker.h" 00011 00012 #include "vmutex.h" 00013 #include "vthread.h" 00014 00015 // VMutexLocker ---------------------------------------------------------------- 00016 00017 VMutexLocker::VMutexLocker(VMutex* mutex, const VString& name, bool lockInitially) 00018 : mMutex(mutex) 00019 , mIsLocked(false) 00020 , mName(name) 00021 { 00022 00023 if (lockInitially) { 00024 this->lock(); 00025 } 00026 } 00027 00028 VMutexLocker::~VMutexLocker() { 00029 if (this->isLocked()) { 00030 // Prevent all exceptions from escaping destructor. 00031 try { 00032 this->unlock(); 00033 } catch (...) {} 00034 } 00035 00036 mMutex = NULL; 00037 } 00038 00039 void VMutexLocker::lock() { 00040 if (mMutex != NULL) { 00041 mMutex->_lock(mName); // specific friend access to private API 00042 mIsLocked = true; 00043 } 00044 } 00045 00046 void VMutexLocker::unlock() { 00047 if ((mMutex != NULL) && this->isLocked()) { 00048 mMutex->_unlock(); // specific friend access to private API 00049 mIsLocked = false; 00050 } 00051 } 00052 00053 void VMutexLocker::yield() { 00054 if (this->isLocked()) { 00055 this->unlock(); // will allow other threads to acquire the mutex 00056 VThread::yield(); 00057 this->lock(); // will block on the mutex if another thread now has it 00058 } else { 00059 VThread::yield(); 00060 } 00061 } 00062 00063 // VMutexUnlocker -------------------------------------------------------------- 00064 00065 VMutexUnlocker::VMutexUnlocker(VMutex* mutex, bool unlockInitially) 00066 : VMutexLocker(mutex, "VMutexUnlocker", false) 00067 { 00068 // We reverse the presumed state and normal construction action vs. VMutexLocker. 00069 mIsLocked = true; // fool unlock() into letting us unlock it next 00070 if (unlockInitially) { 00071 this->unlock(); 00072 } 00073 } 00074 00075 VMutexUnlocker::~VMutexUnlocker() { 00076 // We reverse the normal destruction action vs. VMutexLocker, and must then 00077 // fake out the mIsLocked state so that the base class destructor won't unlock. 00078 if (!this->isLocked()) { 00079 // Prevent all exceptions from escaping destructor. 00080 try { 00081 this->lock(); 00082 } catch (...) {} 00083 } 00084 00085 mIsLocked = false; // fool the base class destructor so it doesn't unlock it 00086 } 00087