Merge pull request #21710 from nextcloud/backport/21074/stable19
[stable19] Fix releasing a shared lock multiple times
This commit is contained in:
commit
42d899c4d5
|
@ -41,6 +41,13 @@ class LockPlugin extends ServerPlugin {
|
|||
*/
|
||||
private $server;
|
||||
|
||||
/**
|
||||
* State of the lock
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
private $isLocked;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
|
@ -48,6 +55,7 @@ class LockPlugin extends ServerPlugin {
|
|||
$this->server = $server;
|
||||
$this->server->on('beforeMethod:*', [$this, 'getLock'], 50);
|
||||
$this->server->on('afterMethod:*', [$this, 'releaseLock'], 50);
|
||||
$this->isLocked = false;
|
||||
}
|
||||
|
||||
public function getLock(RequestInterface $request) {
|
||||
|
@ -67,10 +75,15 @@ class LockPlugin extends ServerPlugin {
|
|||
} catch (LockedException $e) {
|
||||
throw new FileLocked($e->getMessage(), $e->getCode(), $e);
|
||||
}
|
||||
$this->isLocked = true;
|
||||
}
|
||||
}
|
||||
|
||||
public function releaseLock(RequestInterface $request) {
|
||||
// don't try to release the lock if we never locked one
|
||||
if ($this->isLocked === false) {
|
||||
return;
|
||||
}
|
||||
if ($request->getMethod() !== 'PUT' || isset($_SERVER['HTTP_OC_CHUNKED'])) {
|
||||
return;
|
||||
}
|
||||
|
@ -81,6 +94,7 @@ class LockPlugin extends ServerPlugin {
|
|||
}
|
||||
if ($node instanceof Node) {
|
||||
$node->releaseLock(ILockingProvider::LOCK_SHARED);
|
||||
$this->isLocked = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -94,8 +94,12 @@ class MemcacheLockingProvider extends AbstractLockingProvider {
|
|||
*/
|
||||
public function releaseLock(string $path, int $type) {
|
||||
if ($type === self::LOCK_SHARED) {
|
||||
$ownSharedLockCount = $this->getOwnSharedLockCount($path);
|
||||
$newValue = 0;
|
||||
if ($this->getOwnSharedLockCount($path) === 1) {
|
||||
if ($ownSharedLockCount === 0) { // if we are not holding the lock, don't try to release it
|
||||
return;
|
||||
}
|
||||
if ($ownSharedLockCount === 1) {
|
||||
$removed = $this->memcache->cad($path, 1); // if we're the only one having a shared lock we can remove it in one go
|
||||
if (!$removed) { //someone else also has a shared lock, decrease only
|
||||
$newValue = $this->memcache->dec($path);
|
||||
|
|
Loading…
Reference in New Issue