summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorRobin Appelman <robin@icewind.nl>2018-07-05 14:39:10 +0200
committerRobin Appelman <robin@icewind.nl>2018-07-05 14:39:10 +0200
commit3d5acbb1d0944ba00fee9af72f7253e6fc7f787e (patch)
tree48ae7acd74515bd11884d02edc9f241425866d44 /lib
parent42912a0e2500f4ce0ff2f9921539283d4239e8a9 (diff)
downloadnextcloud-server-3d5acbb1d0944ba00fee9af72f7253e6fc7f787e.tar.gz
nextcloud-server-3d5acbb1d0944ba00fee9af72f7253e6fc7f787e.zip
prevent lock values from going negative with memcache backend
This can be caused by the code releasing more locks then it acquires, once the lock value becomes negative it's likely that it will never be able to change into an exclusive lock again. Signed-off-by: Robin Appelman <robin@icewind.nl>
Diffstat (limited to 'lib')
-rw-r--r--lib/private/Lock/MemcacheLockingProvider.php10
1 files changed, 8 insertions, 2 deletions
diff --git a/lib/private/Lock/MemcacheLockingProvider.php b/lib/private/Lock/MemcacheLockingProvider.php
index 55a82b22781..4d1b3dc0bca 100644
--- a/lib/private/Lock/MemcacheLockingProvider.php
+++ b/lib/private/Lock/MemcacheLockingProvider.php
@@ -90,14 +90,20 @@ class MemcacheLockingProvider extends AbstractLockingProvider {
*/
public function releaseLock(string $path, int $type) {
if ($type === self::LOCK_SHARED) {
+ $newValue = 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);
+ $newValue = $this->memcache->dec($path);
}
} else {
// if we own more than one lock ourselves just decrease
- $this->memcache->dec($path);
+ $newValue = $this->memcache->dec($path);
+ }
+
+ // if we somehow release more locks then exists, reset the lock
+ if ($newValue < 0) {
+ $this->memcache->cad($path, $newValue);
}
} else if ($type === self::LOCK_EXCLUSIVE) {
$this->memcache->cad($path, 'exclusive');