Mutex.php 3.92 KB
Newer Older
resurtm committed
1
<?php
2 3 4 5 6
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */
resurtm committed
7 8 9 10 11 12

namespace yii\mutex;

use Yii;
use yii\base\Component;

13 14 15 16
/**
 * @author resurtm <resurtm@gmail.com>
 * @since 2.0
 */
resurtm committed
17 18
abstract class Mutex extends Component
{
19 20 21 22
	/**
	 * @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
	 */
resurtm committed
23
	public $autoRelease = true;
24 25 26
	/**
	 * @var string[] names of the locks acquired in the current PHP process.
	 */
resurtm committed
27 28 29
	private $_locks = array();


30 31 32
	/**
	 * Initializes the mutex component.
	 */
resurtm committed
33 34 35 36 37 38 39 40
	public function init()
	{
		if ($this->autoRelease) {
			register_shutdown_function(array($this, 'shutdownFunction'));
		}
	}

	/**
41
	 * Never call this method directly under any circumstances. This method is intended for internal use only.
resurtm committed
42 43 44 45 46 47 48 49
	 */
	public function shutdownFunction()
	{
		foreach ($this->_locks as $lock) {
			$this->release($lock);
		}
	}

50 51 52 53 54 55
	/**
	 * @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.
	 */
resurtm committed
56 57 58 59 60 61 62 63 64 65
	public function acquireLock($name, $timeout = 0)
	{
		if ($this->acquire($name, $timeout)) {
			$this->_locks[] = $name;
			return true;
		} else {
			return false;
		}
	}

66 67 68 69 70
	/**
	 * Release acquired lock.
	 * @param string $name of the lock to be released. This lock must be already created.
	 * @return boolean lock release result.
	 */
resurtm committed
71 72 73 74 75 76 77 78 79 80
	public function releaseLock($name)
	{
		if ($this->release($name)) {
			unset($this->_locks[array_search($name, $this->_locks)]);
			return true;
		} else {
			return false;
		}
	}

81 82 83 84 85 86
	/**
	 * Checks whether named lock was already opened.
	 * @param string $name of the lock to be checked. This lock must be already created.
	 * @return boolean|null whether named lock was already opened. Returns `null` value in case concrete
	 * mutex implementation does not support this operation.
	 */
resurtm committed
87 88 89 90 91 92 93 94 95
	public function getIsLockAcquired($name)
	{
		if (in_array($name, $this->_locks)) {
			return true;
		} else {
			return $this->getIsAcquired($name);
		}
	}

96 97 98 99 100 101
	/**
	 * Checks whether given lock is local. In other words local lock means that it was opened in the current
	 * PHP process.
	 * @param string $name of the lock to be checked. This lock must be already created.
	 * @return boolean whether named lock was locally acquired.
	 */
resurtm committed
102 103 104 105 106
	public function getIsLockLocal($name)
	{
		return in_array($name, $this->_locks);
	}

107 108 109 110 111 112
	/**
	 * 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.
	 */
resurtm committed
113 114
	abstract protected function acquire($name, $timeout = 0);

115 116 117 118 119
	/**
	 * 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.
	 */
resurtm committed
120 121
	abstract protected function release($name);

122 123 124 125 126 127 128
	/**
	 * This method may optionally be extended by concrete mutex implementations. Checks whether lock has been
	 * already acquired by given name.
	 * @param string $name of the lock to be released.
	 * @return null|boolean whether lock has been already acquired. Returns `null` in case this feature
	 * is not supported by concrete mutex implementation.
	 */
resurtm committed
129 130 131 132 133
	protected function getIsAcquired($name)
	{
		return null;
	}

134 135 136 137 138
	/**
	 * This method should be extended by concrete mutex implementations. Returns whether current mutex
	 * implementation can be used in a distributed environment.
	 * @return boolean whether current mutex implementation can be used in a distributed environment.
	 */
resurtm committed
139 140
	abstract public function getIsDistributed();
}