aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobin Appelman <icewind@owncloud.com>2015-05-19 17:12:09 +0200
committerRobin Appelman <icewind@owncloud.com>2015-06-01 13:22:56 +0200
commite08423f95631a1b06f2de0216c5765552092075c (patch)
treed39516c121367596211655e927c8183e7e2709d0
parent2d63fd77de1cbfdb0a3474cadf99f1dcf4962d5f (diff)
downloadnextcloud-server-e08423f95631a1b06f2de0216c5765552092075c.tar.gz
nextcloud-server-e08423f95631a1b06f2de0216c5765552092075c.zip
release all locks on shutdown
-rw-r--r--lib/base.php2
-rw-r--r--lib/private/lock/memcachelockingprovider.php27
-rw-r--r--lib/public/lock/ilockingprovider.php5
3 files changed, 34 insertions, 0 deletions
diff --git a/lib/base.php b/lib/base.php
index b7f19c96406..09159dc22aa 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -666,6 +666,8 @@ class OC {
//make sure temporary files are cleaned up
$tmpManager = \OC::$server->getTempManager();
register_shutdown_function(array($tmpManager, 'clean'));
+ $lockProvider = \OC::$server->getLockingProvider();
+ register_shutdown_function(array($lockProvider, 'releaseAll'));
if ($systemConfig->getValue('installed', false) && !self::checkUpgrade(false)) {
if (\OC::$server->getConfig()->getAppValue('core', 'backgroundjobs_mode', 'ajax') == 'ajax') {
diff --git a/lib/private/lock/memcachelockingprovider.php b/lib/private/lock/memcachelockingprovider.php
index 9c8c7235462..b2938e3a8ce 100644
--- a/lib/private/lock/memcachelockingprovider.php
+++ b/lib/private/lock/memcachelockingprovider.php
@@ -31,6 +31,11 @@ class MemcacheLockingProvider implements ILockingProvider {
*/
private $memcache;
+ private $acquiredLocks = [
+ 'shared' => [],
+ 'exclusive' => []
+ ];
+
/**
* @param \OCP\IMemcache $memcache
*/
@@ -64,11 +69,16 @@ class MemcacheLockingProvider implements ILockingProvider {
if (!$this->memcache->inc($path)) {
throw new LockedException($path);
}
+ if (!isset($this->acquiredLocks['shared'][$path])) {
+ $this->acquiredLocks['shared'][$path] = 0;
+ }
+ $this->acquiredLocks['shared'][$path]++;
} else {
$this->memcache->add($path, 0);
if (!$this->memcache->cas($path, 0, 'exclusive')) {
throw new LockedException($path);
}
+ $this->acquiredLocks['exclusive'][$path] = true;
}
}
@@ -79,8 +89,25 @@ class MemcacheLockingProvider implements ILockingProvider {
public function releaseLock($path, $type) {
if ($type === self::LOCK_SHARED) {
$this->memcache->dec($path);
+ $this->acquiredLocks['shared'][$path]--;
} else if ($type === self::LOCK_EXCLUSIVE) {
$this->memcache->cas($path, 'exclusive', 0);
+ unset($this->acquiredLocks['exclusive'][$path]);
+ }
+ }
+
+ /**
+ * release all lock acquired by this instance
+ */
+ public function releaseAll() {
+ foreach ($this->acquiredLocks['shared'] as $path => $count) {
+ for ($i = 0; $i < $count; $i++) {
+ $this->releaseLock($path, self::LOCK_SHARED);
+ }
+ }
+
+ foreach ($this->acquiredLocks['exclusive'] as $path => $hasLock) {
+ $this->releaseLock($path, self::LOCK_EXCLUSIVE);
}
}
}
diff --git a/lib/public/lock/ilockingprovider.php b/lib/public/lock/ilockingprovider.php
index 0b17580faac..18fa47fa631 100644
--- a/lib/public/lock/ilockingprovider.php
+++ b/lib/public/lock/ilockingprovider.php
@@ -44,4 +44,9 @@ interface ILockingProvider {
* @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE
*/
public function releaseLock($path, $type);
+
+ /**
+ * release all lock acquired by this instance
+ */
+ public function releaseAll();
}