Completed
Push — fix_travis ( 785058...ce7855 )
by Kamil
02:06
created

LockAbstract::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 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
use NinjaMutex\UnrecoverableMutexException;
13
14
/**
15
 * Abstract lock implementor
16
 *
17
 * @author Kamil Dziedzic <[email protected]>
18
 */
19
abstract class LockAbstract implements LockInterface
20
{
21
    const USLEEP_TIME = 100;
22
23
    /**
24
     * Information which allows to track down process which acquired lock
25
     *
26
     * @var array
27
     */
28
    protected $lockInformation = array();
29
30
    /**
31
     * @var array
32
     */
33
    protected $locks = array();
34
35
    public function __construct()
36
    {
37
        $this->lockInformation = $this->generateLockInformation();
38
    }
39
40
    public function __clone()
41
    {
42
        $this->locks = array();
43
    }
44
45
    /**
46
     * Try to release any obtained locks when object is destroyed
47
     *
48
     * This is a safe guard for cases when your php script dies unexpectedly.
49
     * It's not guaranteed it will work either.
50
     *
51
     * You should not depend on __destruct() to release your locks,
52
     * instead release them with `$released = $this->releaseLock()`A
53
     * and check `$released` if lock was properly released
54
     */
55
    public function __destruct()
56
    {
57
        foreach ($this->locks as $name => $v) {
58
            $released = $this->releaseLock($name);
59
            if (!$released) {
60
                throw new UnrecoverableMutexException(sprintf(
61
                    'Cannot release lock in __destruct(): %s',
62
                    $name
63
                ));
64
            }
65
        }
66
    }
67
68
    /**
69
     * Acquire lock
70
     *
71
     * @param  string   $name    name of lock
72
     * @param  null|int $timeout 1. null if you want blocking lock
73
     *                           2. 0 if you want just lock and go
74
     *                           3. $timeout > 0 if you want to wait for lock some time (in milliseconds)
75
     * @return bool
76
     */
77
    public function acquireLock($name, $timeout = null)
78
    {
79
        $blocking = $timeout === null;
80
        $start = microtime(true);
81
        $end = $start + $timeout / 1000;
82
        $locked = false;
83
        while (!(empty($this->locks[$name]) && $locked = $this->getLock($name, $blocking)) && ($blocking || ($timeout > 0 && microtime(true) < $end))) {
84
            usleep(static::USLEEP_TIME);
85
        }
86
87
        if ($locked) {
88
            $this->locks[$name] = true;
89
90
            return true;
91
        }
92
93
        return false;
94
    }
95
96
    /**
97
     * @param  string $name
98
     * @param  bool   $blocking
99
     * @return bool
100
     */
101
    abstract protected function getLock($name, $blocking);
102
103
    /**
104
     * Information generate by this method allow to track down process which acquired lock
105
     * .
106
     * By default it returns array with:
107
     * 1. pid
108
     * 2. server_ip
109
     * 3. server_name
110
     *
111
     * @return array
112
     */
113
    protected function generateLockInformation()
114
    {
115
        $pid = getmypid();
116
        $hostname = gethostname();
117
        $host = gethostbyname($hostname);
118
119
        // Compose data to one string
120
        $params = array();
121
        $params[] = $pid;
122
        $params[] = $host;
123
        $params[] = $hostname;
124
125
        return $params;
126
    }
127
128
    /**
129
     * Information returned by this method allow to track down process which acquired lock
130
     * .
131
     * @return array
132
     */
133
    protected function getLockInformation()
134
    {
135
        return $this->lockInformation;
136
    }
137
}
138