Completed
Pull Request — master (#7)
by light
03:33
created

FileLock   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 111
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 72.97%

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 0
dl 0
loc 111
ccs 27
cts 37
cp 0.7297
rs 10
c 0
b 0
f 0

6 Methods

Rating   Name   Duplication   Size   Complexity  
A create() 0 4 1
A __construct() 0 10 4
A acquire() 0 19 4
A release() 0 16 3
A isLocked() 0 4 2
A __destory() 0 6 2
1
<?php
2
/**
3
 * Created by PhpStorm.
4
 * User: Jenner
5
 * Date: 2015/8/21
6
 * Time: 14:30
7
 */
8
9
namespace Jenner\SimpleFork\Lock;
10
11
12
/**
13
 * file lock
14
 *
15
 * @package Jenner\SimpleFork\Lock
16
 */
17
class FileLock implements LockInterface
18
{
19
    /**
20
     * @var string lock file
21
     */
22
    protected $file;
23
24
    /**
25
     * @var resource
26
     */
27
    protected $fp;
28
29
    /**
30
     * @var bool
31
     */
32
    protected $locked = false;
33
34
    /**
35
     * create a file lock instance
36
     * if the file is not exists, it will be created
37
     *
38
     * @param string $file lock file
39
     * @return FileLock
40
     */
41 12
    public static function create($file)
42
    {
43 12
        return new FileLock($file);
44
    }
45
46
    /**
47
     * @param $file
48
     */
49 12
    private function __construct($file)
50
    {
51 12
        if (!file_exists($file) || !is_readable($file)) {
52
            throw new \RuntimeException("{$file} is not exists or not readable");
53
        }
54 12
        $this->fp = fopen($file, 'r+');
55 12
        if (!is_resource($this->fp)) {
56
            throw new \RuntimeException("open {$file} failed");
57
        }
58 12
    }
59
60
    /**
61
     * get a lock
62
     *
63
     * @param bool $blocking
64
     * @return mixed
65
     */
66 9
    public function acquire($blocking = true)
67
    {
68 9
        if ($this->locked) {
69 3
            throw new \RuntimeException('already lock by yourself');
70
        }
71
72 9
        if ($blocking) {
73 6
            $locked = flock($this->fp, LOCK_EX);
74 6
        } else {
75 3
            $locked = flock($this->fp, LOCK_EX | LOCK_NB);
76
        }
77
78 9
        if ($locked !== true) {
79 3
            return false;
80
        }
81 9
        $this->locked = true;
82
83 9
        return true;
84
    }
85
86
    /**
87
     * release lock
88
     *
89
     * @return mixed
90
     */
91 9
    public function release()
92
    {
93 9
        if (!$this->locked) {
94 3
            throw new \RuntimeException('release a non lock');
95
        }
96
97 6
        $unlock = flock($this->fp, LOCK_UN);
98 6
        if ($unlock !== true) {
99
            return false;
100
        }
101 6
        fclose($this->fp);
102 6
        $this->fp = null;
103 6
        $this->locked = false;
104
105 6
        return true;
106
    }
107
108
    /**
109
     * is locked
110
     *
111
     * @return mixed
112
     */
113
    public function isLocked()
114
    {
115
        return $this->locked === true ? true : false;
116
    }
117
118
    /**
119
     *
120
     */
121
    public function __destory()
122
    {
123
        if ($this->locked) {
124
            $this->release();
125
        }
126
    }
127
}