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