Skip to content
Snippets Groups Projects
Commit dc1e3620 authored by Owen Winkler's avatar Owen Winkler Committed by Thomas Müller
Browse files

Continued flock work.

parent 5365ae41
Branches
No related tags found
No related merge requests found
......@@ -103,4 +103,5 @@ abstract class StreamWrapper extends Common {
public function stat($path) {
return stat($this->constructUrl($path));
}
}
......@@ -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;
}
......
......@@ -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
......@@ -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
*
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment