Skip to content

Commit 798b3c6

Browse files
committed
Remove released semaphore
1 parent 79b4e87 commit 798b3c6

File tree

2 files changed

+41
-9
lines changed

2 files changed

+41
-9
lines changed

Store/SemaphoreStore.php

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -75,16 +75,20 @@ private function lock(Key $key, $blocking)
7575
return;
7676
}
7777

78-
$resource = sem_get(crc32($key));
78+
$keyId = crc32($key);
79+
$resource = sem_get($keyId);
7980

80-
if (\PHP_VERSION_ID < 50601) {
81-
if (!$blocking) {
82-
throw new NotSupportedException(sprintf('The store "%s" does not supports non blocking locks.', get_class($this)));
83-
}
84-
85-
$acquired = sem_acquire($resource);
81+
if (\PHP_VERSION_ID >= 50601) {
82+
$acquired = @sem_acquire($resource, !$blocking);
83+
} elseif (!$blocking) {
84+
throw new NotSupportedException(sprintf('The store "%s" does not supports non blocking locks.', get_class($this)));
8685
} else {
87-
$acquired = sem_acquire($resource, !$blocking);
86+
$acquired = @sem_acquire($resource);
87+
}
88+
89+
while ($blocking && !$acquired) {
90+
$resource = sem_get($keyId);
91+
$acquired = @sem_acquire($resource);
8892
}
8993

9094
if (!$acquired) {
@@ -106,7 +110,7 @@ public function delete(Key $key)
106110

107111
$resource = $key->getState(__CLASS__);
108112

109-
sem_release($resource);
113+
sem_remove($resource);
110114

111115
$key->removeState(__CLASS__);
112116
}

Tests/Store/SemaphoreStoreTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Lock\Tests\Store;
1313

14+
use Symfony\Component\Lock\Key;
1415
use Symfony\Component\Lock\Store\SemaphoreStore;
1516

1617
/**
@@ -33,4 +34,31 @@ protected function getStore()
3334

3435
return new SemaphoreStore();
3536
}
37+
38+
public function testResourceRemoval()
39+
{
40+
$initialCount = $this->getOpenedSemaphores();
41+
$store = new SemaphoreStore();
42+
$key = new Key(uniqid(__METHOD__, true));
43+
$store->waitAndSave($key);
44+
45+
$this->assertGreaterThan($initialCount, $this->getOpenedSemaphores(), 'Semaphores should have been created');
46+
47+
$store->delete($key);
48+
$this->assertEquals($initialCount, $this->getOpenedSemaphores(), 'All semaphores should be removed');
49+
}
50+
51+
private function getOpenedSemaphores()
52+
{
53+
$lines = explode(PHP_EOL, trim(`ipcs -su`));
54+
if ('------ Semaphore Status --------' !== $lines[0]) {
55+
throw new \Exception('Failed to extract list of opend semaphores. Expect a Semaphore status, got '.implode(PHP_EOL, $lines));
56+
}
57+
list($key, $value) = explode(' = ', $lines[1]);
58+
if ('used arrays' !== $key) {
59+
throw new \Exception('Failed to extract list of opend semaphores. Expect a used arrays key, got '.implode(PHP_EOL, $lines));
60+
}
61+
62+
return (int) $value;
63+
}
3664
}

0 commit comments

Comments
 (0)