* @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);
}
* @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();
*/
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) {
$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) {
$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) {
$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) {
$this->releaseLock($path2, Lock::WRITE);
throw $originalException;
}
+ $this->releaseLock($path1, Lock::READ);
+ $this->releaseLock($path2, Lock::WRITE);
return $result;
}
*/
namespace OCP\Files;
+use OC\Files\Filesystem;
/**
* 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']++;
+
}
/**
return true;
}
+ /**
+ * Release all queued locks on the file
+ * @return bool
+ */
+ public function releaseAll() {
+ return true;
+ }
+
}
\ No newline at end of file