Passed
Push — master ( d02194...22e762 )
by Evgeniy
02:20
created

Mutex::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 4
ccs 3
cts 3
cp 1
crap 1
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Mutex;
6
7
use RuntimeException;
8
9
use function md5;
10
11
/**
12
 * Provides basic functionality for creating drivers {@see MutexFactoryInterface}.
13
 */
14
abstract class Mutex implements MutexInterface
15
{
16
    use RetryAcquireTrait;
17
18
    private string $lockName;
19
    private string $mutexName;
20
21
    /**
22
     * @var array<string, true>
23
     */
24
    private static array $currentProcessLocks = [];
25
26 12
    public function __construct(string $driverName, string $mutexName)
27
    {
28 12
        $this->lockName = md5($driverName . $mutexName);
29 12
        $this->mutexName = $mutexName;
30 12
    }
31
32 9
    public function __destruct()
33
    {
34 9
        $this->release();
35 8
    }
36
37 11
    final public function acquire(int $timeout = 0): bool
38
    {
39 11
        return $this->retryAcquire($timeout, function () use ($timeout): bool {
40 11
            if (!$this->isCurrentProcessLocked() && $this->acquireLock($timeout)) {
41 11
                return self::$currentProcessLocks[$this->lockName] = true;
42
            }
43
44 4
            return false;
45 11
        });
46
    }
47
48 12
    final public function release(): void
49
    {
50 12
        if (!$this->isCurrentProcessLocked()) {
51 7
            return;
52
        }
53
54 12
        if (!$this->releaseLock()) {
55 1
            throw new RuntimeException("Unable to release lock \"$this->mutexName\".");
56
        }
57
58 11
        unset(self::$currentProcessLocks[$this->lockName]);
59 11
    }
60
61
    /**
62
     * Acquires lock.
63
     *
64
     * This method should be extended by a concrete Mutex implementations.
65
     *
66
     * @param int $timeout Time (in seconds) to wait for lock to be released. Defaults to zero meaning that method
67
     * will return false immediately in case lock was already acquired.
68
     *
69
     * @return bool The acquiring result.
70
     */
71
    abstract protected function acquireLock(int $timeout = 0): bool;
72
73
    /**
74
     * Releases lock.
75
     *
76
     * This method should be extended by a concrete Mutex implementations.
77
     *
78
     * @return bool The release result.
79
     */
80
    abstract protected function releaseLock(): bool;
81
82
    /**
83
     * Checks whether a lock has been set in the current process.
84
     *
85
     * @return bool Whether a lock has been set in the current process.
86
     */
87 12
    private function isCurrentProcessLocked(): bool
88
    {
89 12
        return isset(self::$currentProcessLocks[$this->lockName]);
90
    }
91
}
92