Mutex   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 76
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 9
eloc 17
c 1
b 0
f 0
dl 0
loc 76
ccs 19
cts 19
cp 1
rs 10

5 Methods

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