mirror of
https://github.com/Combodo/iTop.git
synced 2026-02-13 07:24:13 +01:00
Allow re-entrance in the same named mutex within the same PHP page.
SVN:trunk[3115]
This commit is contained in:
@@ -31,12 +31,18 @@ class iTopMutex
|
|||||||
{
|
{
|
||||||
protected $sName;
|
protected $sName;
|
||||||
protected $hDBLink;
|
protected $hDBLink;
|
||||||
|
static protected $aAcquiredLocks = array();
|
||||||
|
|
||||||
public function __construct($sName)
|
public function __construct($sName)
|
||||||
{
|
{
|
||||||
// Compute the name of a lock for mysql
|
// Compute the name of a lock for mysql
|
||||||
// Note: the name is server-wide!!!
|
// Note: the name is server-wide!!!
|
||||||
$this->sName = 'itop.'.$sName;
|
$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
|
// 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)
|
// using GET_LOCK anytime on the same session will RELEASE the current and unique session lock (known issue)
|
||||||
@@ -55,17 +61,21 @@ class iTopMutex
|
|||||||
*/
|
*/
|
||||||
public function Lock()
|
public function Lock()
|
||||||
{
|
{
|
||||||
do
|
if (self::$aAcquiredLocks[$this->sName] == 0)
|
||||||
{
|
{
|
||||||
$res = $this->QueryToScalar("SELECT GET_LOCK('".$this->sName."', 3600)");
|
do
|
||||||
if (is_null($res))
|
|
||||||
{
|
{
|
||||||
throw new Exception("Failed to acquire the lock '".$this->sName."'");
|
$res = $this->QueryToScalar("SELECT GET_LOCK('".$this->sName."', 3600)");
|
||||||
|
if (is_null($res))
|
||||||
|
{
|
||||||
|
throw new Exception("Failed to acquire the lock '".$this->sName."'");
|
||||||
|
}
|
||||||
|
// $res === '1' means I hold the lock
|
||||||
|
// $res === '0' means it timed out
|
||||||
}
|
}
|
||||||
// $res === '1' means I hold the lock
|
while ($res !== '1');
|
||||||
// $res === '0' means it timed out
|
|
||||||
}
|
}
|
||||||
while ($res !== '1');
|
self::$aAcquiredLocks[$this->sName]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,6 +84,12 @@ class iTopMutex
|
|||||||
*/
|
*/
|
||||||
public function TryLock()
|
public function TryLock()
|
||||||
{
|
{
|
||||||
|
if (self::$aAcquiredLocks[$this->sName] > 0)
|
||||||
|
{
|
||||||
|
self::$aAcquiredLocks[$this->sName]++;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
$res = $this->QueryToScalar("SELECT GET_LOCK('".$this->sName."', 0)");
|
$res = $this->QueryToScalar("SELECT GET_LOCK('".$this->sName."', 0)");
|
||||||
if (is_null($res))
|
if (is_null($res))
|
||||||
{
|
{
|
||||||
@@ -81,6 +97,10 @@ class iTopMutex
|
|||||||
}
|
}
|
||||||
// $res === '1' means I hold the lock
|
// $res === '1' means I hold the lock
|
||||||
// $res === '0' means it timed out
|
// $res === '0' means it timed out
|
||||||
|
if ($res === '1')
|
||||||
|
{
|
||||||
|
self::$aAcquiredLocks[$this->sName]++;
|
||||||
|
}
|
||||||
return ($res === '1');
|
return ($res === '1');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,7 +109,13 @@ class iTopMutex
|
|||||||
*/
|
*/
|
||||||
public function Unlock()
|
public function Unlock()
|
||||||
{
|
{
|
||||||
$res = $this->QueryToScalar("SELECT RELEASE_LOCK('".$this->sName."')");
|
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]--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user