Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 479919d

Browse filesBrowse 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
Copy full SHA for 479919d

File tree

2 files changed

+35
-11
lines changed
Filter options

2 files changed

+35
-11
lines changed

‎src/Symfony/Component/Cache/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Cache/CHANGELOG.md
+1Lines 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

Copy file name to clipboardExpand all lines: src/Symfony/Component/Cache/LockRegistry.php
+34-11Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.