Files
yii2/framework/mutex/Mutex.php
2014-05-29 11:43:23 +03:00

113 lines
3.4 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace yii\mutex;
use Yii;
use yii\base\Component;
/**
* Mutex component allows mutual execution of the concurrent processes, preventing "race conditions".
* This is achieved by using "lock" mechanism. Each possibly concurrent thread cooperates by acquiring
* the lock before accessing the corresponding data.
*
* Usage example:
*
* ```
* if ($mutex->acquire($mutexName)) {
* // business logic execution
* } else {
* // execution is blocked!
* }
* ```
*
* This class is a base one, which should be extended in order to implement actual lock mechanism.
*
* @author resurtm <resurtm@gmail.com>
* @since 2.0
*/
abstract class Mutex extends Component
{
/**
* @var boolean whether all locks acquired in this process (i.e. local locks) must be released automagically
* before finishing script execution. Defaults to true. Setting this property to true means that all locks
* acquire in this process must be released in any case (regardless any kind of errors or exceptions).
*/
public $autoRelease = true;
/**
* @var string[] names of the locks acquired in the current PHP process.
*/
private $_locks = [];
/**
* Initializes the mutex component.
*/
public function init()
{
if ($this->autoRelease) {
$locks = &$this->_locks;
register_shutdown_function(function () use (&$locks) {
foreach ($locks as $lock) {
$this->release($lock);
}
});
}
}
/**
* Acquires lock by given name.
* @param string $name of the lock to be acquired. Must be unique.
* @param integer $timeout to wait for lock to be released. Defaults to zero meaning that method will return
* false immediately in case lock was already acquired.
* @return boolean lock acquiring result.
*/
public function acquire($name, $timeout = 0)
{
if ($this->acquireLock($name, $timeout)) {
$this->_locks[] = $name;
return true;
} else {
return false;
}
}
/**
* Release acquired lock. This method will return false in case named lock was not found.
* @param string $name of the lock to be released. This lock must be already created.
* @return boolean lock release result: false in case named lock was not found..
*/
public function release($name)
{
if ($this->releaseLock($name)) {
$index = array_search($name, $this->_locks);
if ($index !== false) {
unset($this->_locks[$index]);
}
return true;
} else {
return false;
}
}
/**
* This method should be extended by concrete mutex implementations. Acquires lock by given name.
* @param string $name of the lock to be acquired.
* @param integer $timeout to wait for lock to become released.
* @return boolean acquiring result.
*/
abstract protected function acquireLock($name, $timeout = 0);
/**
* This method should be extended by concrete mutex implementations. Releases lock by given name.
* @param string $name of the lock to be released.
* @return boolean release result.
*/
abstract protected function releaseLock($name);
}