3 namespace Friendica\Core\Lock;
5 use Friendica\Core\Cache\IMemoryCacheDriver;
7 class CacheLockDriver extends AbstractLockDriver
10 * @var \Friendica\Core\Cache\ICacheDriver;
15 * CacheLockDriver constructor.
17 * @param IMemoryCacheDriver $cache The CacheDriver for this type of lock
19 public function __construct(IMemoryCacheDriver $cache)
21 $this->cache = $cache;
26 * @brief Sets a lock for a given name
28 * @param string $key The Name of the lock
29 * @param integer $timeout Seconds until we give up
31 * @return boolean Was the lock successful?
33 public function acquireLock($key, $timeout = 120)
38 $cachekey = self::getCacheKey($key);
41 $lock = $this->cache->get($cachekey);
42 // When we do want to lock something that was already locked by us.
43 if ((int)$lock == getmypid()) {
47 // When we do want to lock something new
49 // At first initialize it with "0"
50 $this->cache->add($cachekey, 0);
51 // Now the value has to be "0" because otherwise the key was used by another process meanwhile
52 if ($this->cache->compareSet($cachekey, 0, getmypid(), 300)) {
54 $this->markAcquire($key);
58 if (!$got_lock && ($timeout > 0)) {
59 usleep(rand(10000, 200000));
61 } while (!$got_lock && ((time() - $start) < $timeout));
67 * @brief Removes a lock if it was set by us
69 * @param string $key Name of the lock
71 public function releaseLock($key)
73 $cachekey = self::getCacheKey($key);
75 $this->cache->compareDelete($cachekey, getmypid());
76 $this->markRelease($key);
80 * @brief Checks, if a key is currently locked to a process
82 * @param string $key The name of the lock
85 public function isLocked($key)
87 $cachekey = self::getCacheKey($key);
88 $lock = $this->cache->get($cachekey);
89 return isset($lock) && ($lock !== false);
93 * @param string $key The original key
94 * @return string The cache key used for the cache
96 private static function getCacheKey($key) {
97 return self::getApp()->get_hostname() . ";lock:" . $key;