]> source.dussan.org Git - nextcloud-server.git/commitdiff
Continued flock work.
authorringmaster <epithet@gmail.com>
Fri, 23 May 2014 14:29:37 +0000 (10:29 -0400)
committerThomas Müller <thomas.mueller@tmit.eu>
Wed, 4 Jun 2014 05:55:44 +0000 (07:55 +0200)
apps/files_external/lib/streamwrapper.php
lib/private/files/storage/wrapper/lockingwrapper.php
lib/public/files/lock.php
lib/public/files/storage.php

index d749f62afe7427a5d54f92cba6c63188aa6e1a7e..44bd9a0161a4cf14ae8d9179a1587dbe73f40f7d 100644 (file)
@@ -103,4 +103,5 @@ abstract class StreamWrapper extends Common {
        public function stat($path) {
                return stat($this->constructUrl($path));
        }
+
 }
index 04a325940bf62fa703e69802eb48a1c00785d74b..42a018fdc663098cdab5d00507978c2e0d6b1356 100644 (file)
@@ -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;
        }
 
index fb1e4b9f1c541c3d2748b2ed22f01c4dea49ef44..cc39e674b509972e98467d8a0b5fb10972b77c11 100644 (file)
@@ -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
index 758cbb273774acda30c68a4e58bfaa99e350ab93..323d20db564ee574448aeff584b6785cc8026988 100644 (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
         *