]> git.mxchange.org Git - friendica.git/blobdiff - src/Core/Lock/DatabaseLockDriver.php
Merge pull request #6704 from tobiasd/20190220-credits
[friendica.git] / src / Core / Lock / DatabaseLockDriver.php
index 6f4b942a4d2a72a4caa55075298f18265646bd16..a137ef12edcac6e6766af4f704128e3ce97085d3 100644 (file)
@@ -2,8 +2,8 @@
 
 namespace Friendica\Core\Lock;
 
-use dba;
-use Friendica\Database\DBM;
+use Friendica\Core\Cache;
+use Friendica\Database\DBA;
 use Friendica\Util\DateTimeFormat;
 
 /**
@@ -11,38 +11,51 @@ use Friendica\Util\DateTimeFormat;
  */
 class DatabaseLockDriver extends AbstractLockDriver
 {
+       /**
+        * The current ID of the process
+        *
+        * @var int
+        */
+       private $pid;
+
+       /**
+        * @param null|int $pid The Id of the current process (null means determine automatically)
+        */
+       public function __construct($pid = null)
+       {
+               $this->pid = isset($pid) ? $pid : getmypid();
+       }
+
        /**
         * (@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` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
+                       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']) {
                                        // We want to lock something that was already locked by us? So we got the lock.
-                                       if ($lock['pid'] == getmypid()) {
+                                       if ($lock['pid'] == $this->pid) {
                                                $got_lock = true;
-                                               $this->markAcquire($key);
                                        }
                                }
                                if (!$lock['locked']) {
-                                       dba::update('locks', ['locked' => true, 'pid' => getmypid(), 'expires' => DateTimeFormat::utc('now + 300seconds')], ['name' => $key]);
+                                       DBA::update('locks', ['locked' => true, 'pid' => $this->pid, 'expires' => DateTimeFormat::utc('now + ' . $ttl . 'seconds')], ['name' => $key]);
                                        $got_lock = true;
-                                       $this->markAcquire($key);
                                }
                        } else {
-                               dba::insert('locks', ['name' => $key, 'locked' => true, 'pid' => getmypid(), 'expires' => DateTimeFormat::utc('now + 300seconds')]);
+                               DBA::insert('locks', ['name' => $key, 'locked' => true, 'pid' => $this->pid, '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));
@@ -55,9 +68,15 @@ class DatabaseLockDriver extends AbstractLockDriver
        /**
         * (@inheritdoc)
         */
-       public function releaseLock($key)
+       public function releaseLock($key, $override = false)
        {
-               dba::delete('locks', ['name' => $key, 'pid' => getmypid()]);
+               if ($override) {
+                       $where = ['name' => $key];
+               } else {
+                       $where = ['name' => $key, 'pid' => $this->pid];
+               }
+
+               DBA::delete('locks', $where);
 
                $this->markRelease($key);
 
@@ -69,7 +88,7 @@ class DatabaseLockDriver extends AbstractLockDriver
         */
        public function releaseAll()
        {
-               dba::delete('locks', ['pid' => getmypid()]);
+               DBA::delete('locks', ['pid' => $this->pid]);
 
                $this->acquiredLocks = [];
        }
@@ -79,9 +98,9 @@ class DatabaseLockDriver extends AbstractLockDriver
         */
        public function isLocked($key)
        {
-               $lock = dba::selectFirst('locks', ['locked'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
+               $lock = DBA::selectFirst('locks', ['locked'], ['`name` = ? AND `expires` >= ?', $key, DateTimeFormat::utcNow()]);
 
-               if (DBM::is_result($lock)) {
+               if (DBA::isResult($lock)) {
                        return $lock['locked'] !== false;
                } else {
                        return false;