]> git.mxchange.org Git - friendica.git/blob - src/Core/Lock/SemaphoreLock.php
wrapping up 2019.12
[friendica.git] / src / Core / Lock / SemaphoreLock.php
1 <?php
2
3 namespace Friendica\Core\Lock;
4
5 use Friendica\Core\Cache;
6
7 class SemaphoreLock extends Lock
8 {
9         private static $semaphore = [];
10
11         public function __construct()
12         {
13                 if (!function_exists('sem_get')) {
14                         throw new \Exception('Semaphore lock not supported');
15                 }
16         }
17
18         /**
19          * (@inheritdoc)
20          */
21         private static function semaphoreKey($key)
22         {
23                 $success = true;
24
25                 $temp = get_temppath();
26
27                 $file = $temp . '/' . $key . '.sem';
28
29                 if (!file_exists($file)) {
30                         $success = !empty(file_put_contents($file, $key));
31                 }
32
33                 return $success ? ftok($file, 'f') : false;
34         }
35
36         /**
37          * (@inheritdoc)
38          */
39         public function acquireLock($key, $timeout = 120, $ttl = Cache\Cache::FIVE_MINUTES)
40         {
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);
45                                 return true;
46                         }
47                 }
48
49                 return false;
50         }
51
52         /**
53          * (@inheritdoc)
54          *
55          * @param bool $override not necessary parameter for semaphore locks since the lock lives as long as the execution
56          *                       of the using function
57          */
58         public function releaseLock($key, $override = false)
59         {
60                 $success = false;
61
62                 if (!empty(self::$semaphore[$key])) {
63                         try {
64                                 $success = @sem_release(self::$semaphore[$key]);
65                                 unset(self::$semaphore[$key]);
66                                 $this->markRelease($key);
67                         } catch (\Exception $exception) {
68                                 $success = false;
69                         }
70                 }
71
72                 return $success;
73         }
74
75         /**
76          * (@inheritdoc)
77          */
78         public function isLocked($key)
79         {
80                 return isset(self::$semaphore[$key]);
81         }
82
83         /**
84          * {@inheritDoc}
85          */
86         public function getName()
87         {
88                 return self::TYPE_SEMAPHORE;
89         }
90
91         /**
92          * {@inheritDoc}
93          */
94         public function getLocks(string $prefix = '')
95         {
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);
99
100                 if (empty($prefix)) {
101                         return $keys;
102                 } else {
103                         $result = [];
104
105                         foreach ($keys as $key) {
106                                 if (strpos($key, $prefix) === 0) {
107                                         array_push($result, $key);
108                                 }
109                         }
110
111                         return $result;
112                 }
113         }
114
115         /**
116          * {@inheritDoc}
117          */
118         public function releaseAll($override = false)
119         {
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);
123         }
124 }