[Pkg-owncloud-commits] [owncloud] 232/457: add method to atomically change between shared and exclusive lock

David Prévot taffit at moszumanska.debian.org
Sun Jun 28 20:06:13 UTC 2015


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch stable8
in repository owncloud.

commit a1372b2fb5acc51eacf70012a6702a96c78e61ff
Author: Robin Appelman <icewind at owncloud.com>
Date:   Fri May 29 14:34:21 2015 +0200

    add method to atomically change between shared and exclusive lock
---
 lib/private/lock/memcachelockingprovider.php | 20 +++++++++++
 lib/public/lock/ilockingprovider.php         |  9 +++++
 tests/lib/lock/lockingprovider.php           | 53 ++++++++++++++++++++++++++++
 3 files changed, 82 insertions(+)

diff --git a/lib/private/lock/memcachelockingprovider.php b/lib/private/lock/memcachelockingprovider.php
index 1334d00..368ff45 100644
--- a/lib/private/lock/memcachelockingprovider.php
+++ b/lib/private/lock/memcachelockingprovider.php
@@ -99,6 +99,26 @@ class MemcacheLockingProvider implements ILockingProvider {
 	}
 
 	/**
+	 * Change the type of an existing lock
+	 *
+	 * @param string $path
+	 * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE
+	 * @throws \OCP\Lock\LockedException
+	 */
+	public function changeLock($path, $targetType) {
+		if ($targetType === self::LOCK_SHARED) {
+			if (!$this->memcache->cas($path, 'exclusive', 1)) {
+				throw new LockedException($path);
+			}
+		} else if ($targetType === self::LOCK_EXCLUSIVE) {
+			// we can only change a shared lock to an exclusive if there's only a single owner of the shared lock
+			if (!$this->memcache->cas($path, 1, 'exclusive')) {
+				throw new LockedException($path);
+			}
+		}
+	}
+
+	/**
 	 * release all lock acquired by this instance
 	 */
 	public function releaseAll() {
diff --git a/lib/public/lock/ilockingprovider.php b/lib/public/lock/ilockingprovider.php
index 18fa47f..6a963b9 100644
--- a/lib/public/lock/ilockingprovider.php
+++ b/lib/public/lock/ilockingprovider.php
@@ -46,6 +46,15 @@ interface ILockingProvider {
 	public function releaseLock($path, $type);
 
 	/**
+	 * Change the type of an existing lock
+	 *
+	 * @param string $path
+	 * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE
+	 * @throws \OCP\Lock\LockedException
+	 */
+	public function changeLock($path, $targetType);
+
+	/**
 	 * release all lock acquired by this instance
 	 */
 	public function releaseAll();
diff --git a/tests/lib/lock/lockingprovider.php b/tests/lib/lock/lockingprovider.php
index 337aa4c..efd6e19 100644
--- a/tests/lib/lock/lockingprovider.php
+++ b/tests/lib/lock/lockingprovider.php
@@ -158,4 +158,57 @@ abstract class LockingProvider extends TestCase {
 			$this->assertEquals('foo', $e->getPath());
 		}
 	}
+
+	public function testChangeLockToExclusive() {
+		$this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
+		$this->instance->changeLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
+		$this->assertFalse($this->instance->isLocked('foo', ILockingProvider::LOCK_SHARED));
+		$this->assertTrue($this->instance->isLocked('foo', ILockingProvider::LOCK_EXCLUSIVE));
+	}
+
+	public function testChangeLockToShared() {
+		$this->instance->acquireLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
+		$this->instance->changeLock('foo', ILockingProvider::LOCK_SHARED);
+		$this->assertFalse($this->instance->isLocked('foo', ILockingProvider::LOCK_EXCLUSIVE));
+		$this->assertTrue($this->instance->isLocked('foo', ILockingProvider::LOCK_SHARED));
+	}
+
+	/**
+	 * @expectedException \OCP\Lock\LockedException
+	 */
+	public function testChangeLockToExclusiveDoubleShared() {
+		$this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
+		$this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
+		$this->instance->changeLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
+	}
+
+	/**
+	 * @expectedException \OCP\Lock\LockedException
+	 */
+	public function testChangeLockToExclusiveNoShared() {
+		$this->instance->changeLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
+	}
+
+	/**
+	 * @expectedException \OCP\Lock\LockedException
+	 */
+	public function testChangeLockToExclusiveFromExclusive() {
+		$this->instance->acquireLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
+		$this->instance->changeLock('foo', ILockingProvider::LOCK_EXCLUSIVE);
+	}
+
+	/**
+	 * @expectedException \OCP\Lock\LockedException
+	 */
+	public function testChangeLockToSharedNoExclusive() {
+		$this->instance->changeLock('foo', ILockingProvider::LOCK_SHARED);
+	}
+
+	/**
+	 * @expectedException \OCP\Lock\LockedException
+	 */
+	public function testChangeLockToSharedFromShared() {
+		$this->instance->acquireLock('foo', ILockingProvider::LOCK_SHARED);
+		$this->instance->changeLock('foo', ILockingProvider::LOCK_SHARED);
+	}
 }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/owncloud.git



More information about the Pkg-owncloud-commits mailing list