Allow re-entrance in the same named mutex within the same PHP page.

SVN:trunk[3115]
This commit is contained in:
Denis Flaven
2014-04-01 09:50:21 +00:00
parent 7a193d1c24
commit ce9806b01c

View File

@@ -31,6 +31,7 @@ class iTopMutex
{
protected $sName;
protected $hDBLink;
static protected $aAcquiredLocks = array();
public function __construct($sName)
{
@@ -38,6 +39,11 @@ class iTopMutex
// Note: the name is server-wide!!!
$this->sName = 'itop.'.$sName;
if (!array_key_exists($this->sName, self::$aAcquiredLocks))
{
self::$aAcquiredLocks[$this->sName] = 0;
}
// It is a MUST to create a dedicated session each time a lock is required, because
// using GET_LOCK anytime on the same session will RELEASE the current and unique session lock (known issue)
$oConfig = utils::GetConfig();
@@ -54,6 +60,8 @@ class iTopMutex
* Acquire the mutex
*/
public function Lock()
{
if (self::$aAcquiredLocks[$this->sName] == 0)
{
do
{
@@ -67,6 +75,8 @@ class iTopMutex
}
while ($res !== '1');
}
self::$aAcquiredLocks[$this->sName]++;
}
/**
* Attempt to acquire the mutex
@@ -74,6 +84,12 @@ class iTopMutex
*/
public function TryLock()
{
if (self::$aAcquiredLocks[$this->sName] > 0)
{
self::$aAcquiredLocks[$this->sName]++;
return true;
}
$res = $this->QueryToScalar("SELECT GET_LOCK('".$this->sName."', 0)");
if (is_null($res))
{
@@ -81,6 +97,10 @@ class iTopMutex
}
// $res === '1' means I hold the lock
// $res === '0' means it timed out
if ($res === '1')
{
self::$aAcquiredLocks[$this->sName]++;
}
return ($res === '1');
}
@@ -88,9 +108,15 @@ class iTopMutex
* Release the mutex
*/
public function Unlock()
{
if (self::$aAcquiredLocks[$this->sName] == 0) return; // Safety net
if (self::$aAcquiredLocks[$this->sName] == 1)
{
$res = $this->QueryToScalar("SELECT RELEASE_LOCK('".$this->sName."')");
}
self::$aAcquiredLocks[$this->sName]--;
}