diff --git a/lib/private/Lock/AbstractLockingProvider.php b/lib/private/Lock/AbstractLockingProvider.php index f96358778c..1886fbea08 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 536b29e2c2..56e581b219 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');