X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FCore%2FLock%2FCacheLockDriver.php;h=18d441ffea09d5a0910ec6ac3ada461db885ab7c;hb=301cdd23dcb5090c72a6a619f18d747e2519df4b;hp=1bb768bd0f180b4abc09d52ad73afcf34cb1ea8f;hpb=ad5ee75159f86010ad0acdf3475eb49f3b9f1192;p=friendica.git diff --git a/src/Core/Lock/CacheLockDriver.php b/src/Core/Lock/CacheLockDriver.php index 1bb768bd0f..18d441ffea 100644 --- a/src/Core/Lock/CacheLockDriver.php +++ b/src/Core/Lock/CacheLockDriver.php @@ -2,7 +2,8 @@ namespace Friendica\Core\Lock; -use Friendica\Core\Cache\ICacheDriver; +use Friendica\Core\Cache; +use Friendica\Core\Cache\IMemoryCacheDriver; class CacheLockDriver extends AbstractLockDriver { @@ -14,76 +15,75 @@ class CacheLockDriver extends AbstractLockDriver /** * CacheLockDriver constructor. * - * @param ICacheDriver $cache The CacheDriver for this type of lock + * @param IMemoryCacheDriver $cache The CacheDriver for this type of lock */ - public function __construct(ICacheDriver $cache) + public function __construct(IMemoryCacheDriver $cache) { $this->cache = $cache; } /** - * - * @brief Sets a lock for a given name - * - * @param string $key The Name of the lock - * @param integer $timeout Seconds until we give up - * - * @return boolean Was the lock successful? + * (@inheritdoc) */ - public function acquireLock($key, $timeout = 120) + public function acquireLock($key, $timeout = 120, $ttl = Cache::FIVE_MINUTES) { $got_lock = false; $start = time(); - $cachekey = get_app()->get_hostname() . ";lock:" . $key; + $cachekey = self::getLockKey($key); do { $lock = $this->cache->get($cachekey); + // When we do want to lock something that was already locked by us. + if ((int)$lock == getmypid()) { + $got_lock = true; + } - if (!is_bool($lock)) { - $pid = (int)$lock; - - // When the process id isn't used anymore, we can safely claim the lock for us. - // Or we do want to lock something that was already locked by us. - if (!posix_kill($pid, 0) || ($pid == getmypid())) { - $lock = false; + // When we do want to lock something new + if (is_null($lock)) { + // At first initialize it with "0" + $this->cache->add($cachekey, 0); + // Now the value has to be "0" because otherwise the key was used by another process meanwhile + if ($this->cache->compareSet($cachekey, 0, getmypid(), $ttl)) { + $got_lock = true; + $this->markAcquire($key); } } - if (is_bool($lock)) { - $this->cache->set($cachekey, getmypid(), 300); - $got_lock = true; - } if (!$got_lock && ($timeout > 0)) { usleep(rand(10000, 200000)); } } while (!$got_lock && ((time() - $start) < $timeout)); - $this->markAcquire($key); - return $got_lock; } /** - * @brief Removes a lock if it was set by us - * - * @param string $key Name of the lock - * - * @return mixed + * (@inheritdoc) */ public function releaseLock($key) { - $cachekey = get_app()->get_hostname() . ";lock:" . $key; - $lock = $this->cache->get($cachekey); - - if (!is_bool($lock)) { - if ((int)$lock == getmypid()) { - $this->cache->delete($cachekey); - } - } + $cachekey = self::getLockKey($key); + $this->cache->compareDelete($cachekey, getmypid()); $this->markRelease($key); + } + + /** + * (@inheritdoc) + */ + public function isLocked($key) + { + $cachekey = self::getLockKey($key); + $lock = $this->cache->get($cachekey); + return isset($lock) && ($lock !== false); + } - return; + /** + * @param string $key The original key + * @return string The cache key used for the cache + */ + private static function getLockKey($key) { + return "lock:" . $key; } }