3 namespace Friendica\Core\Lock;
5 use Friendica\Core\Cache;
6 use Friendica\Core\Cache\IMemoryCache;
8 class CacheLock extends Lock
11 * @var \Friendica\Core\Cache\ICache;
16 * CacheLock constructor.
18 * @param IMemoryCache $cache The CacheDriver for this type of lock
20 public function __construct(IMemoryCache $cache)
22 $this->cache = $cache;
28 public function acquireLock($key, $timeout = 120, $ttl = Cache::FIVE_MINUTES)
33 $cachekey = self::getLockKey($key);
36 $lock = $this->cache->get($cachekey);
37 // When we do want to lock something that was already locked by us.
38 if ((int)$lock == getmypid()) {
42 // When we do want to lock something new
44 // At first initialize it with "0"
45 $this->cache->add($cachekey, 0);
46 // Now the value has to be "0" because otherwise the key was used by another process meanwhile
47 if ($this->cache->compareSet($cachekey, 0, getmypid(), $ttl)) {
49 $this->markAcquire($key);
53 if (!$got_lock && ($timeout > 0)) {
54 usleep(rand(10000, 200000));
56 } while (!$got_lock && ((time() - $start) < $timeout));
64 public function releaseLock($key, $override = false)
66 $cachekey = self::getLockKey($key);
69 $return = $this->cache->delete($cachekey);
71 $return = $this->cache->compareDelete($cachekey, getmypid());
73 $this->markRelease($key);
81 public function isLocked($key)
83 $cachekey = self::getLockKey($key);
84 $lock = $this->cache->get($cachekey);
85 return isset($lock) && ($lock !== false);
89 * @param string $key The original key
91 * @return string The cache key used for the cache
93 private static function getLockKey($key)
95 return "lock:" . $key;