Skip to content

Commit 85ce4d2

Browse files
committed
Fix issue found by Scrutinizer
1 parent 3f4edbc commit 85ce4d2

File tree

3 files changed

+92
-35
lines changed

3 files changed

+92
-35
lines changed

src/FileLock.php

+66-35
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ class FileLock implements Lock
2020
private $fh;
2121
private $remove_on_release;
2222

23+
private $logger;
24+
25+
/**
26+
* @param string $lock_file path to file
27+
* @param string|null $identifier resource identifier (default to $lock_file) for logging
28+
* @param string|null $owner owner name for logging
29+
* @param boolean $remove_on_release remove file on release if no other lock remains
30+
*/
2331
public function __construct($lock_file, $identifier = null, $owner = null, $remove_on_release = false)
2432
{
2533
$this->lock_file = $lock_file;
@@ -30,33 +38,53 @@ public function __construct($lock_file, $identifier = null, $owner = null, $remo
3038
$this->logger = new NullLogger;
3139
}
3240

41+
/**
42+
* @param boolean $exclusive true for an exclusive lock, false for shared one
43+
* @param boolean $blocking true to wait for lock to be available, false to throw exception instead of waiting
44+
* @inherit
45+
*/
3346
public function acquire($exclusive = FileLock::EXCLUSIVE, $blocking = FileLock::NON_BLOCKING)
3447
{
35-
$operation = ($exclusive ? LOCK_EX : LOCK_SH) | ($blocking ? 0 : LOCK_NB);
36-
37-
if (!flock($this->fh(), $operation)) {
38-
$this->logger->debug(($exclusive ?
39-
'{owner} could not acquire exclusive lock on {identifier}':
40-
'{owner} could not acquire shared lock on {identifier}'
41-
), [
42-
'identifier' => $this->identifier,
43-
'owner' => $this->owner
44-
]);
45-
46-
throw new Exception(($exclusive ?
47-
'Could not acquire exclusive lock on '.$this->identifier:
48-
'Could not acquire shared lock on '.$this->identifier
49-
));
48+
if ($exclusive === FileLock::EXCLUSIVE) {
49+
$lock_type = 'exclusive';
50+
$operation = LOCK_EX;
51+
} else {
52+
$lock_type = 'shared';
53+
$operation = LOCK_SH;
54+
}
5055

56+
if ($blocking === FileLock::NON_BLOCKING) {
57+
$operation |= LOCK_NB;
5158
}
5259

53-
$this->logger->debug(($exclusive ?
54-
'{owner} exclusive lock acquired on {identifier}':
55-
'{owner} shared lock acquired on {identifier}'
56-
), [
60+
$this->tryAcquire($operation, $lock_type);
61+
}
62+
63+
/**
64+
* try to acquire lock on file, throw in case of faillure
65+
* @param int $operation
66+
* @param string $lock_type lock type description
67+
* @return void
68+
* @see https://php.net/flock
69+
*/
70+
private function tryAcquire($operation, $lock_type)
71+
{
72+
$log_data = [
5773
'identifier' => $this->identifier,
58-
'owner' => $this->owner
59-
]);
74+
'owner' => $this->owner,
75+
'lock_type' => $lock_type
76+
];
77+
78+
if (!$this->flock($operation)) {
79+
$this->logger->debug('{owner} could not acquire {lock_type} lock on {identifier}', $log_data);
80+
81+
throw new Exception(
82+
'Could not acquire '.$lock_type.' lock on '.$this->identifier
83+
);
84+
85+
}
86+
87+
$this->logger->debug('{owner} {lock_type} lock acquired on {identifier}', $log_data);
6088
}
6189

6290
public function release()
@@ -65,22 +93,18 @@ public function release()
6593
return;
6694
}
6795

68-
if($this->remove_on_release && flock($this->fh, LOCK_EX)) {
69-
fclose($this->fh);
70-
$this->fh = null;
96+
if($this->remove_on_release && $this->flock(LOCK_EX)) {
7197
unlink($this->lock_file);
72-
} else {
73-
flock($this->fh, LOCK_UN);
7498
}
7599

100+
$this->flock(LOCK_UN);
101+
fclose($this->fh);
102+
$this->fh = null;
76103

77-
$this->logger->debug(
78-
'{owner} lock released on {identifier}',
79-
[
80-
'identifier' => $this->identifier,
81-
'owner' => $this->owner
82-
]
83-
);
104+
$this->logger->debug('{owner} lock released on {identifier}', [
105+
'identifier' => $this->identifier,
106+
'owner' => $this->owner
107+
]);
84108
}
85109

86110
public function setLogger(LoggerInterface $logger)
@@ -93,12 +117,19 @@ public function __destruct()
93117
$this->release();
94118
}
95119

96-
private function fh()
120+
/**
121+
* @return boolean
122+
*/
123+
private function flock($operation)
97124
{
98125
if ($this->fh === null) {
99126
$this->fh = fopen($this->lock_file, 'c');
100127
}
101128

102-
return $this->fh;
129+
if (!is_resource($this->fh)) {
130+
throw new Exception('Could not open lock file '.$this->lock_file);
131+
}
132+
133+
return flock($this->fh, $operation);
103134
}
104135
}

src/Lock.php

+15
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,22 @@
66

77
interface Lock
88
{
9+
/**
10+
* Acquire a lock on the resource
11+
* @return void
12+
*/
913
public function acquire();
14+
15+
/**
16+
* Release lock on the resource
17+
* @return void
18+
*/
1019
public function release();
20+
21+
/**
22+
* Replace lock logger
23+
* @param LoggerInterface $logger
24+
* @return void
25+
*/
1126
public function setLogger(LoggerInterface $logger);
1227
}

src/LockFactory.php

+11
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,17 @@
66

77
interface LockFactory
88
{
9+
/**
10+
* Create a lock handle on $resource
11+
* @param string $resource resource identifier
12+
* @param string|null $owner owner name (for logging)
13+
* @return Lock
14+
*/
915
public function create($resource, $owner = null);
16+
17+
/**
18+
* @param LoggerInterface $logger
19+
* @return void
20+
*/
1021
public function setLogger(LoggerInterface $logger);
1122
}

0 commit comments

Comments
 (0)