From 49ad0fcfa9eba188d5032f8ffcd95d7cc235db80 Mon Sep 17 00:00:00 2001
From: Robin Appelman <icewind@owncloud.com>
Date: Fri, 29 Apr 2016 12:54:33 +0200
Subject: [PATCH] optimize releaselock for memcache based locking backends

---
 lib/private/Lock/AbstractLockingProvider.php | 4 ++++
 lib/private/Lock/MemcacheLockingProvider.php | 9 +++++++--
 2 files changed, 11 insertions(+), 2 deletions(-)

diff --git a/lib/private/Lock/AbstractLockingProvider.php b/lib/private/Lock/AbstractLockingProvider.php
index f96358778c1..1886fbea082 100644
--- a/lib/private/Lock/AbstractLockingProvider.php
+++ b/lib/private/Lock/AbstractLockingProvider.php
@@ -116,4 +116,8 @@ abstract class AbstractLockingProvider implements ILockingProvider {
 			$this->releaseLock($path, self::LOCK_EXCLUSIVE);
 		}
 	}
+
+	protected function getOwnSharedLockCount($path) {
+		return isset($this->acquiredLocks['shared'][$path]) ? $this->acquiredLocks['shared'][$path] : 0;
+	}
 }
diff --git a/lib/private/Lock/MemcacheLockingProvider.php b/lib/private/Lock/MemcacheLockingProvider.php
index 536b29e2c28..56e581b2192 100644
--- a/lib/private/Lock/MemcacheLockingProvider.php
+++ b/lib/private/Lock/MemcacheLockingProvider.php
@@ -88,9 +88,14 @@ class MemcacheLockingProvider extends AbstractLockingProvider {
 	 */
 	public function releaseLock($path, $type) {
 		if ($type === self::LOCK_SHARED) {
-			if (isset($this->acquiredLocks['shared'][$path]) and $this->acquiredLocks['shared'][$path] > 0) {
+			if ($this->getOwnSharedLockCount($path) === 1) {
+				$removed = $this->memcache->cad($path, 1); // if we're the only one having a shared lock we can remove it in one go
+				if (!$removed) { //someone else also has a shared lock, decrease only
+					$this->memcache->dec($path);
+				}
+			} else {
+				// if we own more than one lock ourselves just decrease
 				$this->memcache->dec($path);
-				$this->memcache->cad($path, 0);
 			}
 		} else if ($type === self::LOCK_EXCLUSIVE) {
 			$this->memcache->cad($path, 'exclusive');
-- 
GitLab