3 namespace Friendica\Core\Lock;
5 use Friendica\Core\Cache;
7 class SemaphoreLock extends Lock
9 private static $semaphore = [];
11 public function __construct()
13 if (!function_exists('sem_get')) {
14 throw new \Exception('Semaphore lock not supported');
21 private static function semaphoreKey($key)
25 $temp = get_temppath();
27 $file = $temp . '/' . $key . '.sem';
29 if (!file_exists($file)) {
30 $success = !empty(file_put_contents($file, $key));
33 return $success ? ftok($file, 'f') : false;
39 public function acquire($key, $timeout = 120, $ttl = Cache\Cache::FIVE_MINUTES)
41 self::$semaphore[$key] = sem_get(self::semaphoreKey($key));
42 if (!empty(self::$semaphore[$key])) {
43 if ((bool)sem_acquire(self::$semaphore[$key], ($timeout === 0))) {
44 $this->markAcquire($key);
55 * @param bool $override not necessary parameter for semaphore locks since the lock lives as long as the execution
56 * of the using function
58 public function release($key, $override = false)
62 if (!empty(self::$semaphore[$key])) {
64 $success = @sem_release(self::$semaphore[$key]);
65 unset(self::$semaphore[$key]);
66 $this->markRelease($key);
67 } catch (\Exception $exception) {
78 public function isLocked($key)
80 return isset(self::$semaphore[$key]);
86 public function getName()
88 return self::TYPE_SEMAPHORE;
94 public function getLocks(string $prefix = '')
96 // We can just return our own semaphore keys, since we don't know
97 // the state of other semaphores, even if the .sem files exists
98 $keys = array_keys(self::$semaphore);
100 if (empty($prefix)) {
105 foreach ($keys as $key) {
106 if (strpos($key, $prefix) === 0) {
107 array_push($result, $key);
118 public function releaseAll($override = false)
120 // Semaphores are just alive during a run, so there is no need to release
121 // You can just release your own locks
122 return parent::releaseAll($override);