X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FCore%2FLock%2FDatabaseLockDriver.php;h=a8788d1f45bf1400b9e96a125c10c28bc9891394;hb=f2ca3e5be44192c486e8e3af2a993e065ad40a7d;hp=9b415753fceecec0663900c682a2e8d5618b1539;hpb=ad5ee75159f86010ad0acdf3475eb49f3b9f1192;p=friendica.git diff --git a/src/Core/Lock/DatabaseLockDriver.php b/src/Core/Lock/DatabaseLockDriver.php index 9b415753fc..a8788d1f45 100644 --- a/src/Core/Lock/DatabaseLockDriver.php +++ b/src/Core/Lock/DatabaseLockDriver.php @@ -2,8 +2,9 @@ namespace Friendica\Core\Lock; -use dba; -use Friendica\Database\DBM; +use Friendica\Core\Cache; +use Friendica\Database\DBA; +use Friendica\Util\DateTimeFormat; /** * Locking driver that stores the locks in the database @@ -11,79 +12,77 @@ use Friendica\Database\DBM; class DatabaseLockDriver extends AbstractLockDriver { /** - * @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(); do { - dba::lock('locks'); - $lock = dba::selectFirst('locks', ['locked', 'pid'], ['name' => $key]); + DBA::lock('locks'); + $lock = DBA::selectFirst('locks', ['locked', 'pid'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]); - if (DBM::is_result($lock)) { + if (DBA::isResult($lock)) { if ($lock['locked']) { - // When the process id isn't used anymore, we can safely claim the lock for us. - if (!posix_kill($lock['pid'], 0)) { - $lock['locked'] = false; - } // We want to lock something that was already locked by us? So we got the lock. if ($lock['pid'] == getmypid()) { $got_lock = true; } } if (!$lock['locked']) { - dba::update('locks', ['locked' => true, 'pid' => getmypid()], ['name' => $key]); + DBA::update('locks', ['locked' => true, 'pid' => getmypid(), 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')], ['name' => $key]); $got_lock = true; } } else { - dba::insert('locks', ['name' => $key, 'locked' => true, 'pid' => getmypid()]); + DBA::insert('locks', ['name' => $key, 'locked' => true, 'pid' => getmypid(), 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')]); $got_lock = true; + $this->markAcquire($key); } - dba::unlock(); + DBA::unlock(); if (!$got_lock && ($timeout > 0)) { usleep(rand(100000, 2000000)); } } 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) { - dba::delete('locks', ['locked' => false, 'pid' => 0], ['name' => $key, 'pid' => getmypid()]); + DBA::delete('locks', ['name' => $key, 'pid' => getmypid()]); - $this->releaseLock($key); + $this->markRelease($key); return; } /** - * @brief Removes all lock that were set by us - * - * @return void + * (@inheritdoc) */ public function releaseAll() { - dba::delete('locks', ['locked' => false, 'pid' => 0], ['pid' => getmypid()]); + DBA::delete('locks', ['pid' => getmypid()]); $this->acquiredLocks = []; } + + /** + * (@inheritdoc) + */ + public function isLocked($key) + { + $lock = DBA::selectFirst('locks', ['locked'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]); + + if (DBA::isResult($lock)) { + return $lock['locked'] !== false; + } else { + return false; + } + } }