]> git.mxchange.org Git - friendica.git/blob - src/Core/Lock/DatabaseLockDriver.php
Update use statement lists with new Friendica\Database\dba class
[friendica.git] / src / Core / Lock / DatabaseLockDriver.php
1 <?php
2
3 namespace Friendica\Core\Lock;
4
5 use Friendica\Core\Cache;
6 use Friendica\Database\dba;
7 use Friendica\Database\DBM;
8 use Friendica\Util\DateTimeFormat;
9
10 /**
11  * Locking driver that stores the locks in the database
12  */
13 class DatabaseLockDriver extends AbstractLockDriver
14 {
15         /**
16          * (@inheritdoc)
17          */
18         public function acquireLock($key, $timeout = 120, $ttl = Cache::FIVE_MINUTES)
19         {
20                 $got_lock = false;
21                 $start = time();
22
23                 do {
24                         dba::lock('locks');
25                         $lock = dba::selectFirst('locks', ['locked', 'pid'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
26
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()) {
31                                                 $got_lock = true;
32                                         }
33                                 }
34                                 if (!$lock['locked']) {
35                                         dba::update('locks', ['locked' => true, 'pid' => getmypid(), 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')], ['name' => $key]);
36                                         $got_lock = true;
37                                 }
38                         } else {
39                                 dba::insert('locks', ['name' => $key, 'locked' => true, 'pid' => getmypid(), 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')]);
40                                 $got_lock = true;
41                                 $this->markAcquire($key);
42                         }
43
44                         dba::unlock();
45
46                         if (!$got_lock && ($timeout > 0)) {
47                                 usleep(rand(100000, 2000000));
48                         }
49                 } while (!$got_lock && ((time() - $start) < $timeout));
50
51                 return $got_lock;
52         }
53
54         /**
55          * (@inheritdoc)
56          */
57         public function releaseLock($key)
58         {
59                 dba::delete('locks', ['name' => $key, 'pid' => getmypid()]);
60
61                 $this->markRelease($key);
62
63                 return;
64         }
65
66         /**
67          * (@inheritdoc)
68          */
69         public function releaseAll()
70         {
71                 dba::delete('locks', ['pid' => getmypid()]);
72
73                 $this->acquiredLocks = [];
74         }
75
76         /**
77          * (@inheritdoc)
78          */
79         public function isLocked($key)
80         {
81                 $lock = dba::selectFirst('locks', ['locked'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
82
83                 if (DBM::is_result($lock)) {
84                         return $lock['locked'] !== false;
85                 } else {
86                         return false;
87                 }
88         }
89 }