-
Notifications
You must be signed in to change notification settings - Fork 0
/
Lock.php
141 lines (122 loc) · 3.25 KB
/
Lock.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
<?php
namespace Locker;
/**
* Class to represent lock.
*
* @author Ian Babrou <ibobrik@gmail.com>
* @class
*/
class Lock {
/**
* Locker which this lock belongs to.
*
* @var Locker
*/
private $Locker;
/**
* Resource name to lock.
*
* @var string
*/
private $name;
/**
* Sequence number from Locker.
*
* @var int
*/
private $sequence;
/**
* Flag of being locked.
*
* @var bool
*/
private $acquired = false;
/**
* Constructor, must be only called from Locker::createLock.
*
* @param Locker $Locker Locker which this lock belongs to.
* @param string $name Resource name to lock.
* @param int $sequence Sequence number from Locker.
*/
public function __construct(Locker $Locker, $name, $sequence) {
$this->Locker = $Locker;
$this->name = $name;
$this->sequence = $sequence;
}
/**
* Acquire lock with wait timeout and work timeout.
*
* @param int $wait Time to wait for lock in milliseconds.
* @param int $timeout Time to acquire lock for in milliseconds.
* @throws LockerLockReuseException
* @throws LockerWaitTimeoutException
*/
public function acquire($wait, $timeout) {
if (!$this->sequence) {
throw new LockerLockReuseException('Trying to reuse lock ' . $this->name);
}
$result = $this->Locker->lock($this->name, $this->sequence, $wait, $timeout);
if (!$result) {
throw new LockerWaitTimeoutException('Wait timeout exceed for lock ' . $this->name);
}
$this->acquired = true;
}
/**
* Release lock. Released lock should not be reused again.
*
* @param bool $panic Flag to throw exception if lock has been lost.
* @throws LockerLostLockException
* @throws LockerUnlockWithoutLockException
*/
public function release($panic = false) {
if (!$this->isAcquired()) {
throw new LockerUnlockWithoutLockException('Trying to unlock lock ' . $this->name .
' without lock');
}
$result = $this->Locker->unlock($this->sequence);
$this->reset();
if ($panic && !$result) {
throw new LockerLostLockException('Lost lock ' . $this->name);
}
}
/**
* Destructor to release lock on object destruction
* and unregister it from Locker.
*/
public function __destruct() {
if ($this->isAcquired()) {
$this->release();
} else {
if ($this->getSequence()) {
$this->reset();
}
}
}
/**
* Reset lock to make it invalid if locker connection
* is broken or after release.
*/
public function reset() {
if ($this->sequence) {
$this->Locker->unregister($this);
}
$this->sequence = false;
$this->acquired = false;
}
/**
* Determine is lock acquired or not.
*
* @return bool
*/
public function isAcquired() {
return $this->acquired;
}
/**
* Return sequence number from Locker.
*
* @return int
*/
public function getSequence() {
return $this->sequence;
}
}