-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathCacheLockUtils.php
More file actions
87 lines (80 loc) · 3.19 KB
/
CacheLockUtils.php
File metadata and controls
87 lines (80 loc) · 3.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
<?php
namespace WebSharks\CometCache\Pro\Traits\Shared;
use WebSharks\CometCache\Pro\Classes;
trait CacheLockUtils
{
/**
* Get an exclusive lock on the cache directory.
*
* @since 150422 Rewrite.
*
* @throws \Exception If {@link \sem_get()} not available and there's
* no writable tmp directory for {@link \flock()} either.
* @throws \Exception If unable to obtain an exclusive lock by any available means.
* @return array Lock type & resource handle needed to unlock later or FALSE if disabled by filter.
*
*
* @note This call is blocking; i.e. it will not return a lock until a lock becomes possible.
* In short, this will block the caller until such time as write access becomes possible.
*/
public function cacheLock()
{
if (apply_filters(GLOBAL_NS.'\\share::disable_cache_locking', false)
|| apply_filters(GLOBAL_NS.'_disable_cache_locking', false)
) {
return false; // Disabled cache locking.
}
if (!($wp_config_file = $this->findWpConfigFile())) {
throw new \Exception(__('Unable to find the wp-config.php file.', SLUG_TD));
}
$lock_type = 'flock'; // Default lock type.
$lock_type = apply_filters(GLOBAL_NS.'\\share::cache_lock_lock_type', $lock_type);
$lock_type = apply_filters(GLOBAL_NS.'_cache_lock_type', $lock_type);
if (!in_array($lock_type, ['flock', 'sem'], true)) {
$lock_type = 'flock'; // Default lock type.
}
if ($lock_type === 'sem' && $this->functionIsPossible('sem_get')) {
if (($ipc_key = ftok($wp_config_file, 'w'))) {
if (($resource = sem_get($ipc_key, 1)) && sem_acquire($resource)) {
return ['type' => 'sem', 'resource' => $resource];
}
}
}
if (!($tmp_dir = $this->getTmpDir())) {
throw new \Exception(__('No writable tmp directory.', SLUG_TD));
}
$inode_key = fileinode($wp_config_file);
$mutex = $tmp_dir.'/'.SLUG_TD.'-'.$inode_key.'.lock';
if (!($resource = fopen($mutex, 'wb')) || !flock($resource, LOCK_EX)) {
throw new \Exception(__('Unable to obtain an exclusive lock.', SLUG_TD));
}
@chmod($mutex, 0666); // See https://git.io/v2WAt
return ['type' => 'flock', 'resource' => $resource];
}
/**
* Release an exclusive lock on the cache directory.
*
* @since 150422 Rewrite. Updated 151002 to remove the `array` typecast.
*
* @param array|mixed $lock Type & resource.
*/
public function cacheUnlock($lock)
{
if (!is_array($lock)) {
return; // Not possible.
// Or, they disabled cache locking.
}
if (empty($lock['type']) || empty($lock['resource'])) {
return; // Not possible.
}
if (!is_resource($lock['resource'])) {
return; // Not possible.
}
if ($lock['type'] === 'sem') {
sem_release($lock['resource']);
} elseif ($lock['type'] === 'flock') {
flock($lock['resource'], LOCK_UN);
fclose($lock['resource']);
}
}
}