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)
23 $file = self::keyToFile($key);
25 if (!file_exists($file)) {
26 file_put_contents($file, $key);
29 return ftok($file, 'f');
33 * Returns the full path to the semaphore file
35 * @param string $key The key of the semaphore
37 * @return string The full path
39 private static function keyToFile($key)
41 $temp = get_temppath();
43 return $temp . '/' . $key . '.sem';
49 public function acquireLock($key, $timeout = 120, $ttl = Cache\Cache::FIVE_MINUTES)
51 self::$semaphore[$key] = sem_get(self::semaphoreKey($key));
52 if (self::$semaphore[$key]) {
53 if (sem_acquire(self::$semaphore[$key], ($timeout == 0))) {
54 $this->markAcquire($key);
65 public function releaseLock($key, $override = false)
69 if (!empty(self::$semaphore[$key])) {
71 $success = @sem_release(self::$semaphore[$key]);
72 if (file_exists(self::keyToFile($key)) && $success) {
73 $success = unlink(self::keyToFile($key));
75 unset(self::$semaphore[$key]);
76 $this->markRelease($key);
77 } catch (\Exception $exception) {
80 } else if ($override) {
81 if ($this->acquireLock($key)) {
82 $success = $this->releaseLock($key, true);
92 public function isLocked($key)
94 return isset(self::$semaphore[$key]);
100 public function getName()
102 return self::TYPE_SEMAPHORE;
108 public function getLocks(string $prefix = '')
110 $temp = get_temppath();
112 foreach (glob(sprintf('%s/%s*.sem', $temp, $prefix)) as $lock) {
113 $lock = pathinfo($lock, PATHINFO_FILENAME);
114 if(sem_get(self::semaphoreKey($lock))) {
125 public function releaseAll($override = false)
127 $success = parent::releaseAll($override);
129 $temp = get_temppath();
130 foreach (glob(sprintf('%s/*.sem', $temp)) as $lock) {
131 $lock = pathinfo($lock, PATHINFO_FILENAME);
132 if (!$this->releaseLock($lock, true)) {