Continued flock work.
This commit is contained in:
parent
5365ae416e
commit
dc1e3620d2
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue