3 namespace Friendica\Core\Lock;
6 use Friendica\Database\DBM;
7 use Friendica\Util\DateTimeFormat;
10 * Locking driver that stores the locks in the database
12 class DatabaseLockDriver extends AbstractLockDriver
17 public function acquire($key, $timeout = 120)
24 $lock = dba::selectFirst('locks', ['locked', 'pid'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
26 if (DBM::is_result($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()) {
31 $this->markAcquire($key);
34 if (!$lock['locked']) {
35 dba::update('locks', ['locked' => true, 'pid' => getmypid(), 'expires' => DateTimeFormat::utc('now + 300seconds')], ['name' => $key]);
37 $this->markAcquire($key);
40 dba::insert('locks', ['name' => $key, 'locked' => true, 'pid' => getmypid(), 'expires' => DateTimeFormat::utc('now + 300seconds')]);
42 $this->markAcquire($key);
47 if (!$got_lock && ($timeout > 0)) {
48 usleep(rand(100000, 2000000));
50 } while (!$got_lock && ((time() - $start) < $timeout));
58 public function release($key)
60 dba::delete('locks', ['name' => $key, 'pid' => getmypid()]);
62 $this->markRelease($key);
70 public function releaseAll()
72 dba::delete('locks', ['pid' => getmypid()]);
74 $this->acquiredLocks = [];
80 public function isLocked($key)
82 $lock = dba::selectFirst('locks', ['locked'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
84 if (DBM::is_result($lock)) {
85 return $lock['locked'] !== false;