storage->getLocalFile($path)); if(!isset($this->locks[$path])) { $this->locks[$path] = new Lock($path); } $this->locks[$path]->addLock($lockType); return $this->locks[$path]; } /** * Release an existing lock * @param string $path Path to file, relative to this storage * @return bool true on success, false on failure */ protected function releaseLock($path, $lockType, $releaseAll = false){ $path = Filesystem::normalizePath($this->storage->getLocalFile($path)); if(isset($this->locks[$path])) { if($releaseAll) { return $this->locks[$path]->releaseAll(); } else { return $this->locks[$path]->release($lockType); } } return true; } /** * see http://php.net/manual/en/function.file_get_contents.php * @param string $path * @return string * @throws \Exception */ public function file_get_contents($path) { try { $this->getLock($path, Lock::READ); $result = $this->storage->file_get_contents($path); } catch(\Exception $originalException) { // Need to release the lock before more operations happen in upstream exception handlers $this->releaseLock($path, Lock::READ); throw $originalException; } $this->releaseLock($path, Lock::READ); return $result; } public function file_put_contents($path, $data) { try { $this->getLock($path, Lock::WRITE); $result = $this->storage->file_put_contents($path, $data); } catch(\Exception $originalException) { // Release lock, throw original exception $this->releaseLock($path, Lock::WRITE); throw $originalException; } $this->releaseLock($path, Lock::WRITE); return $result; } public function copy($path1, $path2) { try { $this->getLock($path1, Lock::READ); $this->getLock($path2, Lock::WRITE); $result = $this->storage->copy($path1, $path2); } catch(\Exception $originalException) { // Release locks, throw original exception $this->releaseLock($path1, Lock::READ); $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 { $this->getLock($path1, Lock::READ); $this->getLock($path2, Lock::WRITE); $result = $this->storage->rename($path1, $path2); } catch(\Exception $originalException) { // Release locks, throw original exception $this->releaseLock($path1, Lock::READ); $this->releaseLock($path2, Lock::WRITE); throw $originalException; } $this->releaseLock($path1, Lock::READ); $this->releaseLock($path2, Lock::WRITE); return $result; } }