FlockLock   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 126
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 1

Test Coverage

Coverage 84.44%

Importance

Changes 0
Metric Value
wmc 17
lcom 1
cbo 1
dl 0
loc 126
ccs 38
cts 45
cp 0.8444
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A getLock() 0 19 4
A releaseLock() 0 12 3
A getFilePath() 0 4 1
A setupFileHandle() 0 15 3
A __clone() 0 5 1
A __destruct() 0 6 2
A isLocked() 0 8 2
1
<?php
2
/**
3
 * This file is part of ninja-mutex.
4
 *
5
 * (C) Kamil Dziedzic <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
namespace NinjaMutex\Lock;
11
12
/**
13
 * Lock implementor using flock
14
 *
15
 * @author Kamil Dziedzic <[email protected]>
16
 */
17
class FlockLock extends LockAbstract
18
{
19
    protected $dirname;
20
    protected $files = array();
21
22
    /**
23
     * @param string $dirname
24
     */
25
    public function __construct($dirname)
26
    {
27
        parent::__construct();
28
29
        $this->dirname = $dirname;
30
    }
31
32
    /**
33
     * @param  string $name
34
     * @param  bool   $blocking
35
     * @return bool
36
     */
37 32
    protected function getLock($name, $blocking)
38
    {
39 32
        if (!$this->setupFileHandle($name)) {
40
            return false;
41
        }
42
43 32
        $options = LOCK_EX;
44
45
        // Check if we don't want to wait until lock is acquired
46 32
        if (!$blocking) {
47 30
            $options |= LOCK_NB;
48 30
        }
49
50 32
        if (!flock($this->files[$name], $options)) {
51 4
            return false;
52
        }
53
54 32
        return true;
55
    }
56
57
    /**
58
     * Release lock
59
     *
60
     * @param  string $name name of lock
61
     * @return bool
62
     */
63 32
    public function releaseLock($name)
64
    {
65 32
        if (isset($this->files[$name]) && flock($this->files[$name], LOCK_UN)) {
66 32
            unset($this->locks[$name]);
67 32
            fclose($this->files[$name]);
68 32
            unset($this->files[$name]);
69 32
70
            return true;
71 32
        }
72
73
        return false;
74 4
    }
75
76
    /**
77
     * @param  string $name
78
     * @return string
79
     */
80
    protected function getFilePath($name)
81 32
    {
82
        return $this->dirname . DIRECTORY_SEPARATOR . $name . '.lock';
83 32
    }
84
85
    /**
86
     * @param  string $name
87
     * @return bool
88
     */
89
    protected function setupFileHandle($name)
90 32
    {
91
        if (isset($this->files[$name])) {
92 32
            return true;
93
        }
94
95
        $file = fopen($this->getFilePath($name), 'c');
96 32
        if (false === $file) {
97 32
            return false;
98
        }
99
100
        $this->files[$name] = $file;
101 32
102
        return true;
103 32
    }
104
105
    public function __clone()
106 10
    {
107
        parent::__clone();
108 10
        $this->files = array();
109 10
    }
110 10
111
    /**
112
     * Try to release any obtained locks when object is destroyed
113
     *
114
     * This is a safe guard for cases when your php script dies unexpectedly.
115
     * It's not guaranteed it will work either.
116
     *
117
     * You should not depend on __destruct() to release your locks,
118
     * instead release them with `$released = $this->releaseLock()`A
119
     * and check `$released` if lock was properly released
120
     */
121
    public function __destruct()
122 10
    {
123
        while (null !== $file = array_pop($this->files)) {
124 10
            fclose($file);
125 6
        }
126 6
    }
127 10
128
    /**
129
     * Check if lock is locked
130
     *
131
     * @param  string $name name of lock
132
     * @return bool
133
     */
134
    public function isLocked($name)
135 14
    {
136
        if ($this->acquireLock($name, 0)) {
137 14
            return !$this->releaseLock($name);
138 6
        }
139
140
        return true;
141 14
    }
142
}
143