3 namespace Friendica\Core\Lock;
5 use Friendica\Core\Cache;
6 use Friendica\Database\DBA;
7 use Friendica\Database\DBM;
8 use Friendica\Util\DateTimeFormat;
11 * Locking driver that stores the locks in the database
13 class DatabaseLockDriver extends AbstractLockDriver
18 public function acquireLock($key, $timeout = 120, $ttl = Cache::FIVE_MINUTES)
25 $lock = DBA::selectFirst('locks', ['locked', 'pid'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
27 if (DBM::is_result($lock)) {
28 if ($lock['locked']) {
29 // We want to lock something that was already locked by us? So we got the lock.
30 if ($lock['pid'] == getmypid()) {
34 if (!$lock['locked']) {
35 DBA::update('locks', ['locked' => true, 'pid' => getmypid(), 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')], ['name' => $key]);
39 DBA::insert('locks', ['name' => $key, 'locked' => true, 'pid' => getmypid(), 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')]);
41 $this->markAcquire($key);
46 if (!$got_lock && ($timeout > 0)) {
47 usleep(rand(100000, 2000000));
49 } while (!$got_lock && ((time() - $start) < $timeout));
57 public function releaseLock($key)
59 DBA::delete('locks', ['name' => $key, 'pid' => getmypid()]);
61 $this->markRelease($key);
69 public function releaseAll()
71 DBA::delete('locks', ['pid' => getmypid()]);
73 $this->acquiredLocks = [];
79 public function isLocked($key)
81 $lock = DBA::selectFirst('locks', ['locked'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
83 if (DBM::is_result($lock)) {
84 return $lock['locked'] !== false;