FlockLock::getFilePath()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
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