3 namespace Friendica\Core\Lock;
5 use Friendica\Core\Cache;
6 use Friendica\Database\DBA;
7 use Friendica\Util\DateTimeFormat;
10 * Locking driver that stores the locks in the database
12 class DatabaseLockDriver extends AbstractLockDriver
17 public function acquireLock($key, $timeout = 120, $ttl = Cache::FIVE_MINUTES)
24 $lock = DBA::selectFirst('locks', ['locked', 'pid'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
26 if (DBA::isResult($lock)) {
27 if ($lock['locked']) {
28 // We want to lock something that was already locked by us? So we got the lock.
29 if ($lock['pid'] == getmypid()) {
33 if (!$lock['locked']) {
34 DBA::update('locks', ['locked' => true, 'pid' => getmypid(), 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')], ['name' => $key]);
38 DBA::insert('locks', ['name' => $key, 'locked' => true, 'pid' => getmypid(), 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')]);
40 $this->markAcquire($key);
45 if (!$got_lock && ($timeout > 0)) {
46 usleep(rand(100000, 2000000));
48 } while (!$got_lock && ((time() - $start) < $timeout));
56 public function releaseLock($key)
58 DBA::delete('locks', ['name' => $key, 'pid' => getmypid()]);
60 $this->markRelease($key);
68 public function releaseAll()
70 DBA::delete('locks', ['pid' => getmypid()]);
72 $this->acquiredLocks = [];
78 public function isLocked($key)
80 $lock = DBA::selectFirst('locks', ['locked'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
82 if (DBA::isResult($lock)) {
83 return $lock['locked'] !== false;