3 namespace Friendica\Core\Lock;
5 use Friendica\Core\BaseLock;
6 use Friendica\Core\Cache\Duration;
8 class SemaphoreLock extends BaseLock
10 private static $semaphore = [];
12 public function __construct()
14 if (!function_exists('sem_get')) {
15 throw new \Exception('Semaphore lock not supported');
22 private static function semaphoreKey($key)
26 $temp = get_temppath();
28 $file = $temp . '/' . $key . '.sem';
30 if (!file_exists($file)) {
31 $success = !empty(file_put_contents($file, $key));
34 return $success ? ftok($file, 'f') : false;
40 public function acquire($key, $timeout = 120, $ttl = Duration::FIVE_MINUTES)
42 self::$semaphore[$key] = sem_get(self::semaphoreKey($key));
43 if (!empty(self::$semaphore[$key])) {
44 if ((bool)sem_acquire(self::$semaphore[$key], ($timeout === 0))) {
45 $this->markAcquire($key);
56 * @param bool $override not necessary parameter for semaphore locks since the lock lives as long as the execution
57 * of the using function
59 public function release($key, $override = false)
63 if (!empty(self::$semaphore[$key])) {
65 $success = @sem_release(self::$semaphore[$key]);
66 unset(self::$semaphore[$key]);
67 $this->markRelease($key);
68 } catch (\Exception $exception) {
79 public function isLocked($key)
81 return isset(self::$semaphore[$key]);
87 public function getName()
89 return Type::SEMAPHORE;
95 public function getLocks(string $prefix = '')
97 // We can just return our own semaphore keys, since we don't know
98 // the state of other semaphores, even if the .sem files exists
99 $keys = array_keys(self::$semaphore);
101 if (empty($prefix)) {
106 foreach ($keys as $key) {
107 if (strpos($key, $prefix) === 0) {
108 array_push($result, $key);
119 public function releaseAll($override = false)
121 // Semaphores are just alive during a run, so there is no need to release
122 // You can just release your own locks
123 return parent::releaseAll($override);