Completed
Push — master ( 95a175...1c4965 )
by Dmitry
12:22
created

Mutex::releaseLock()

Size

Total Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 1
c 0
b 0
f 0
ccs 0
cts 0
cp 0
nc 1
1
<?php
2
/**
3
 * @link http://www.yiiframework.com/
4
 * @copyright Copyright (c) 2008 Yii Software LLC
5
 * @license http://www.yiiframework.com/license/
6
 */
7
8
namespace yii\mutex;
9
10
use yii\base\Component;
11
12
/**
13
 * The Mutex component allows mutual execution of concurrent processes in order to prevent "race conditions".
14
 * This is achieved by using a "lock" mechanism. Each possibly concurrent thread cooperates by acquiring
15
 * a lock before accessing the corresponding data.
16
 *
17
 * Usage example:
18
 *
19
 * ```
20
 * if ($mutex->acquire($mutexName)) {
21
 *     // business logic execution
22
 * } else {
23
 *     // execution is blocked!
24
 * }
25
 * ```
26
 *
27
 * This is a base class, which should be extended in order to implement the actual lock mechanism.
28
 *
29
 * @author resurtm <[email protected]>
30
 * @since 2.0
31
 */
32
abstract class Mutex extends Component
33
{
34
    /**
35
     * @var bool whether all locks acquired in this process (i.e. local locks) must be released automatically
36
     * before finishing script execution. Defaults to true. Setting this property to true means that all locks
37
     * acquired in this process must be released (regardless of errors or exceptions).
38
     */
39
    public $autoRelease = true;
40
41
    /**
42
     * @var string[] names of the locks acquired by the current PHP process.
43
     */
44
    private $_locks = [];
45
46
47
    /**
48
     * Initializes the Mutex component.
49
     */
50 4
    public function init()
51
    {
52 4
        if ($this->autoRelease) {
53 4
            $locks = &$this->_locks;
54 4
            register_shutdown_function(function () use (&$locks) {
55
                foreach ($locks as $lock) {
56
                    $this->release($lock);
57
                }
58 4
            });
59 4
        }
60 4
    }
61
62
    /**
63
     * Acquires a lock by name.
64
     * @param string $name of the lock to be acquired. Must be unique.
65
     * @param int $timeout time to wait for lock to be released. Defaults to zero meaning that method will return
66
     * false immediately in case lock was already acquired.
67
     * @return bool lock acquiring result.
68
     */
69 7
    public function acquire($name, $timeout = 0)
70
    {
71 7
        if ($this->acquireLock($name, $timeout)) {
72 7
            $this->_locks[] = $name;
73
74 7
            return true;
75
        } else {
76 3
            return false;
77
        }
78
    }
79
80
    /**
81
     * Releases acquired lock. This method will return false in case the lock was not found.
82
     * @param string $name of the lock to be released. This lock must already exist.
83
     * @return bool lock release result: false in case named lock was not found..
84
     */
85 4
    public function release($name)
86
    {
87 4
        if ($this->releaseLock($name)) {
88 4
            $index = array_search($name, $this->_locks);
89 4
            if ($index !== false) {
90 4
                unset($this->_locks[$index]);
91 4
            }
92
93 4
            return true;
94
        } else {
95
            return false;
96
        }
97
    }
98
99
    /**
100
     * This method should be extended by a concrete Mutex implementations. Acquires lock by name.
101
     * @param string $name of the lock to be acquired.
102
     * @param int $timeout time to wait for the lock to be released.
103
     * @return bool acquiring result.
104
     */
105
    abstract protected function acquireLock($name, $timeout = 0);
106
107
    /**
108
     * This method should be extended by a concrete Mutex implementations. Releases lock by given name.
109
     * @param string $name of the lock to be released.
110
     * @return bool release result.
111
     */
112
    abstract protected function releaseLock($name);
113
}
114