-
Notifications
You must be signed in to change notification settings - Fork 88
/
Copy pathMutex.php
61 lines (56 loc) · 2.07 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
<?php
declare(strict_types=1);
namespace Malkusch\Lock\Mutex;
use Malkusch\Lock\Exception\ExecutionOutsideLockException;
use Malkusch\Lock\Exception\LockAcquireException;
use Malkusch\Lock\Exception\LockReleaseException;
use Malkusch\Lock\Util\DoubleCheckedLocking;
/**
* Mutex interface for exclusive execution.
*/
interface 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.
*
* @template T
*
* @param callable(): T $code The synchronized execution callback
*
* @return T
*
* @throws \Exception The execution callback threw an exception
* @throws LockAcquireException The mutex could not be acquired, no further side effects
* @throws LockReleaseException The mutex could not be released, the code was already executed
* @throws ExecutionOutsideLockException Some code has been executed outside of the lock
*/
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(static function () use ($bankAccount, $amount) {
* return $bankAccount->getBalance() >= $amount;
* })->then(static function () use ($bankAccount, $amount) {
* return $bankAccount->withdraw($amount);
* });
* </code>
*
* @param callable(): bool $check Callback that decides if the lock should be acquired and if the synchronized
* callback should be executed after acquiring the lock
*
* @return DoubleCheckedLocking The double-checked locking pattern
*/
public function check(callable $check): DoubleCheckedLocking;
}