summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorringmaster <epithet@gmail.com>2014-05-23 10:29:37 -0400
committerThomas Müller <thomas.mueller@tmit.eu>2014-06-04 07:55:44 +0200
commitdc1e3620d239ad4fbfb3a80610949abb0c9a4ecd (patch)
tree160109fc8b4489039531e17dc9137fb2d36f7d0b /lib
parent5365ae416ec1a2c1dd868707cbb01f50bbe9027d (diff)
downloadnextcloud-server-dc1e3620d239ad4fbfb3a80610949abb0c9a4ecd.tar.gz
nextcloud-server-dc1e3620d239ad4fbfb3a80610949abb0c9a4ecd.zip
Continued flock work.
Diffstat (limited to 'lib')
-rw-r--r--lib/private/files/storage/wrapper/lockingwrapper.php34
-rw-r--r--lib/public/files/lock.php52
-rw-r--r--lib/public/files/storage.php1
3 files changed, 63 insertions, 24 deletions
diff --git a/lib/private/files/storage/wrapper/lockingwrapper.php b/lib/private/files/storage/wrapper/lockingwrapper.php
index 04a325940bf..42a018fdc66 100644
--- a/lib/private/files/storage/wrapper/lockingwrapper.php
+++ b/lib/private/files/storage/wrapper/lockingwrapper.php
@@ -34,7 +34,7 @@ class LockingWrapper extends Wrapper {
* @return bool|\OCP\Files\Lock Lock instance on success, false on failure
*/
protected function getLock($path, $lockType){
- $path = Filesystem::normalizePath($path);
+ $path = Filesystem::normalizePath($this->storage->getLocalFile($path));
if(!isset($this->locks[$path])) {
$this->locks[$path] = new Lock($path);
}
@@ -48,7 +48,7 @@ class LockingWrapper extends Wrapper {
* @return bool true on success, false on failure
*/
protected function releaseLock($path, $lockType, $releaseAll = false){
- $path = Filesystem::normalizePath($path);
+ $path = Filesystem::normalizePath($this->storage->getLocalFile($path));
if(isset($this->locks[$path])) {
if($releaseAll) {
return $this->locks[$path]->releaseAll();
@@ -68,9 +68,7 @@ class LockingWrapper extends Wrapper {
*/
public function file_get_contents($path) {
try {
- if (!$this->getLock($path, Lock::READ)) {
- throw new LockNotAcquiredException($path, Lock::READ);
- }
+ $this->getLock($path, Lock::READ);
$result = $this->storage->file_get_contents($path);
}
catch(\Exception $originalException) {
@@ -78,14 +76,13 @@ class LockingWrapper extends Wrapper {
$this->releaseLock($path, Lock::READ);
throw $originalException;
}
+ $this->releaseLock($path, Lock::READ);
return $result;
}
public function file_put_contents($path, $data) {
try {
- if (!$this->getLock($path, Lock::WRITE)) {
- throw new LockNotAcquiredException($path, Lock::WRITE);
- }
+ $this->getLock($path, Lock::WRITE);
$result = $this->storage->file_put_contents($path, $data);
}
catch(\Exception $originalException) {
@@ -93,18 +90,15 @@ class LockingWrapper extends Wrapper {
$this->releaseLock($path, Lock::WRITE);
throw $originalException;
}
+ $this->releaseLock($path, Lock::WRITE);
return $result;
}
public function copy($path1, $path2) {
try {
- if (!$this->getLock($path1, Lock::READ)) {
- throw new LockNotAcquiredException($path1, Lock::READ);
- }
- if (!$this->getLock($path2, Lock::WRITE)) {
- throw new LockNotAcquiredException($path2, Lock::WRITE);
- }
+ $this->getLock($path1, Lock::READ);
+ $this->getLock($path2, Lock::WRITE);
$result = $this->storage->copy($path1, $path2);
}
catch(\Exception $originalException) {
@@ -113,17 +107,15 @@ class LockingWrapper extends Wrapper {
$this->releaseLock($path2, Lock::WRITE);
throw $originalException;
}
+ $this->releaseLock($path1, Lock::READ);
+ $this->releaseLock($path2, Lock::WRITE);
return $result;
}
public function rename($path1, $path2) {
try {
- if (!$this->getLock($path1, Lock::READ)) {
- throw new LockNotAcquiredException($path1, Lock::READ);
- }
- if (!$this->getLock($path2, Lock::WRITE)) {
- throw new LockNotAcquiredException($path2, Lock::WRITE);
- }
+ $this->getLock($path1, Lock::READ);
+ $this->getLock($path2, Lock::WRITE);
$result = $this->storage->rename($path1, $path2);
}
catch(\Exception $originalException) {
@@ -132,6 +124,8 @@ class LockingWrapper extends Wrapper {
$this->releaseLock($path2, Lock::WRITE);
throw $originalException;
}
+ $this->releaseLock($path1, Lock::READ);
+ $this->releaseLock($path2, Lock::WRITE);
return $result;
}
diff --git a/lib/public/files/lock.php b/lib/public/files/lock.php
index fb1e4b9f1c5..cc39e674b50 100644
--- a/lib/public/files/lock.php
+++ b/lib/public/files/lock.php
@@ -17,6 +17,7 @@
*/
namespace OCP\Files;
+use OC\Files\Filesystem;
/**
* Class Lock
@@ -29,13 +30,50 @@ class Lock {
/** @var string $path Filename of the file as represented in storage */
protected $path;
+ /** @var array $stack A stack of lock data */
+ protected $stack = array();
+
+ /** @var int $retries Number of lock retries to attempt */
+ public static $retries = 40;
+
+ /** @var int $retryInterval Milliseconds between retries */
+ public static $retryInterval = 50;
+
+ /**
+ * Constructor for the lock instance
+ * @param string $path Absolute pathname for a local file on which to obtain a lock
+ */
public function __construct($path) {
- $this->path = $path;
+ $this->path = Filesystem::normalizePath($path);
}
+ /**
+ * @param integer $lockType A constant representing the type of lock to queue
+ */
public function addLock($lockType) {
- // This class is a stub/base for classes that implement locks
- // We don't actually care what kind of lock we're queuing here
+ \OC_Log::write('lock', sprintf('INFO: Lock type %d requested for %s', $lockType, $this->path), \OC_Log::DEBUG);
+ $timeout = self::$retries;
+
+ if(!isset($this->stack[$lockType])) {
+ // does lockfile exist?
+ // yes
+ // Acquire exclusive lock on lockfile?
+ // yes
+ // Delete lockfile, release lock
+ // no
+ // Sleep for configurable milliseconds - start over
+ // no
+ // Acquire shared lock on original file?
+ // yes
+ // Capture handle, return for action
+ // no
+ // Sleep for configurable milliseconds - start over
+ $handle = 1;
+
+ $this->stack[$lockType] = array('handle' => $handle, 'count' => 0);
+ }
+ $this->stack[$lockType]['count']++;
+
}
/**
@@ -45,4 +83,12 @@ class Lock {
return true;
}
+ /**
+ * Release all queued locks on the file
+ * @return bool
+ */
+ public function releaseAll() {
+ return true;
+ }
+
} \ No newline at end of file
diff --git a/lib/public/files/storage.php b/lib/public/files/storage.php
index 758cbb27377..323d20db564 100644
--- a/lib/public/files/storage.php
+++ b/lib/public/files/storage.php
@@ -35,7 +35,6 @@ namespace OCP\Files;
* All paths passed to the storage are relative to the storage and should NOT have a leading slash.
*/
interface Storage {
-
/**
* $parameters is a free form array with the configuration options needed to construct the storage
*