Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 479919d

Browse files
committed
feature #41989 [Cache] make LockRegistry use semaphores when possible (nicolas-grekas)
This PR was merged into the 5.4 branch. Discussion ---------- [Cache] make `LockRegistry` use semaphores when possible | Q | A | ------------- | --- | Branch? | 5.4 | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | - | License | MIT | Doc PR | - Commits ------- 87632b7 [Cache] make `LockRegistry` use semaphores when possible
2 parents 356c953 + 87632b7 commit 479919d

File tree

2 files changed

+35
-11
lines changed

2 files changed

+35
-11
lines changed

src/Symfony/Component/Cache/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ CHANGELOG
44
5.4
55
---
66

7+
* Make `LockRegistry` use semaphores when possible
78
* Deprecate `DoctrineProvider` because this class has been added to the `doctrine/cache` package
89

910
5.3

src/Symfony/Component/Cache/LockRegistry.php

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
final class LockRegistry
2828
{
2929
private static $openedFiles = [];
30-
private static $lockedFiles;
30+
private static $lockedKeys;
3131

3232
/**
3333
* The number of items in this list controls the max number of concurrent processes.
@@ -75,32 +75,40 @@ public static function setFiles(array $files): array
7575
fclose($file);
7676
}
7777
}
78-
self::$openedFiles = self::$lockedFiles = [];
78+
self::$openedFiles = self::$lockedKeys = [];
7979

8080
return $previousFiles;
8181
}
8282

8383
public static function compute(callable $callback, ItemInterface $item, bool &$save, CacheInterface $pool, \Closure $setMetadata = null, LoggerInterface $logger = null)
8484
{
85-
if ('\\' === \DIRECTORY_SEPARATOR && null === self::$lockedFiles) {
85+
if ('\\' === \DIRECTORY_SEPARATOR && null === self::$lockedKeys) {
8686
// disable locking on Windows by default
87-
self::$files = self::$lockedFiles = [];
87+
self::$files = self::$lockedKeys = [];
8888
}
8989

90-
$key = self::$files ? abs(crc32($item->getKey())) % \count(self::$files) : -1;
90+
$key = unpack('i', md5($item->getKey(), true))[1];
9191

92-
if ($key < 0 || (self::$lockedFiles[$key] ?? false) || !$lock = self::open($key)) {
92+
if (!\function_exists('sem_get')) {
93+
$key = self::$files ? abs($key) % \count(self::$files) : null;
94+
}
95+
96+
if (null === $key || (self::$lockedKeys[$key] ?? false) || !$lock = self::open($key)) {
9397
return $callback($item, $save);
9498
}
9599

96100
while (true) {
97101
try {
98102
// race to get the lock in non-blocking mode
99-
$locked = flock($lock, \LOCK_EX | \LOCK_NB, $wouldBlock);
103+
if ($wouldBlock = \function_exists('sem_get')) {
104+
$locked = @sem_acquire($lock, true);
105+
} else {
106+
$locked = flock($lock, \LOCK_EX | \LOCK_NB, $wouldBlock);
107+
}
100108

101109
if ($locked || !$wouldBlock) {
102110
$logger && $logger->info(sprintf('Lock %s, now computing item "{key}"', $locked ? 'acquired' : 'not supported'), ['key' => $item->getKey()]);
103-
self::$lockedFiles[$key] = true;
111+
self::$lockedKeys[$key] = true;
104112

105113
$value = $callback($item, $save);
106114

@@ -115,12 +123,23 @@ public static function compute(callable $callback, ItemInterface $item, bool &$s
115123

116124
return $value;
117125
}
126+
118127
// if we failed the race, retry locking in blocking mode to wait for the winner
119128
$logger && $logger->info('Item "{key}" is locked, waiting for it to be released', ['key' => $item->getKey()]);
120-
flock($lock, \LOCK_SH);
129+
130+
if (\function_exists('sem_get')) {
131+
$lock = sem_get($key);
132+
@sem_acquire($lock);
133+
} else {
134+
flock($lock, \LOCK_SH);
135+
}
121136
} finally {
122-
flock($lock, \LOCK_UN);
123-
unset(self::$lockedFiles[$key]);
137+
if (\function_exists('sem_get')) {
138+
sem_remove($lock);
139+
} else {
140+
flock($lock, \LOCK_UN);
141+
}
142+
unset(self::$lockedKeys[$key]);
124143
}
125144
static $signalingException, $signalingCallback;
126145
$signalingException = $signalingException ?? unserialize("O:9:\"Exception\":1:{s:16:\"\0Exception\0trace\";a:0:{}}");
@@ -145,6 +164,10 @@ public static function compute(callable $callback, ItemInterface $item, bool &$s
145164

146165
private static function open(int $key)
147166
{
167+
if (\function_exists('sem_get')) {
168+
return sem_get($key);
169+
}
170+
148171
if (null !== $h = self::$openedFiles[$key] ?? null) {
149172
return $h;
150173
}

0 commit comments

Comments
 (0)