-
Notifications
You must be signed in to change notification settings - Fork 90
/
Mutex.php
65 lines (60 loc) · 2.18 KB
/
Mutex.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
<?php
declare(strict_types=1);
namespace malkusch\lock\mutex;
use malkusch\lock\util\DoubleCheckedLocking;
/**
* The mutex provides methods for exclusive execution.
*
* @author Markus Malkusch <markus@malkusch.de>
* @link bitcoin:1P5FAZ4QhXCuwYPnLZdk3PJsqePbu1UDDA Donations
* @license WTFPL
*/
abstract class Mutex
{
/**
* Executes a block of code exclusively.
*
* This method implements Java's synchronized semantic. I.e. this method
* waits until a lock could be acquired, executes the code exclusively and
* releases the lock.
*
* The code block may throw an exception. In this case the lock will be
* released as well.
*
* @param callable $code The synchronized execution callback.
* @throws \Exception The execution callback threw an exception.
* @throws \malkusch\lock\exception\LockAcquireException The mutex could not
* be acquired, no further side effects.
* @throws \malkusch\lock\exception\LockReleaseException The mutex could not
* be released, the code was already executed.
* @throws \malkusch\lock\exception\ExecutionOutsideLockException Some code
* has been executed outside of the lock.
* @return mixed The return value of the execution callback.
*/
abstract public function synchronized(callable $code);
/**
* Performs a double-checked locking pattern.
*
* Call {@link \malkusch\lock\util\DoubleCheckedLocking::then()} on the
* returned object.
*
* Example:
* <code>
* $result = $mutex->check(function () use ($bankAccount, $amount) {
* return $bankAccount->getBalance() >= $amount;
* })->then(function () use ($bankAccount, $amount) {
* return $bankAccount->withdraw($amount);
* });
* </code>
*
* @param callable $check Callback that decides if the lock should be
* acquired and if the synchronized callback should be executed after
* acquiring the lock.
* @return \malkusch\lock\util\DoubleCheckedLocking The double-checked
* locking pattern.
*/
public function check(callable $check): DoubleCheckedLocking
{
return new DoubleCheckedLocking($this, $check);
}
}