You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

LockManager.php 2.5KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <?php
  2. namespace OC\Files\Lock;
  3. use OCP\Files\Lock\ILock;
  4. use OCP\Files\Lock\ILockManager;
  5. use OCP\Files\Lock\ILockProvider;
  6. use OCP\Files\Lock\LockContext;
  7. use OCP\PreConditionNotMetException;
  8. use Psr\Container\ContainerExceptionInterface;
  9. use Psr\Container\NotFoundExceptionInterface;
  10. class LockManager implements ILockManager {
  11. private ?string $lockProviderClass = null;
  12. private ?ILockProvider $lockProvider = null;
  13. private ?LockContext $lockInScope = null;
  14. public function registerLockProvider(ILockProvider $lockProvider): void {
  15. if ($this->lockProvider) {
  16. throw new PreConditionNotMetException('There is already a registered lock provider');
  17. }
  18. $this->lockProvider = $lockProvider;
  19. }
  20. public function registerLazyLockProvider(string $lockProviderClass): void {
  21. if ($this->lockProviderClass || $this->lockProvider) {
  22. throw new PreConditionNotMetException('There is already a registered lock provider');
  23. }
  24. $this->lockProviderClass = $lockProviderClass;
  25. }
  26. private function getLockProvider(): ?ILockProvider {
  27. if ($this->lockProvider) {
  28. return $this->lockProvider;
  29. }
  30. if ($this->lockProviderClass) {
  31. try {
  32. $this->lockProvider = \OCP\Server::get($this->lockProviderClass);
  33. } catch (NotFoundExceptionInterface|ContainerExceptionInterface $e) {
  34. }
  35. }
  36. return $this->lockProvider;
  37. }
  38. public function isLockProviderAvailable(): bool {
  39. return $this->getLockProvider() !== null;
  40. }
  41. public function runInScope(LockContext $lock, callable $callback): void {
  42. if (!$this->getLockProvider()) {
  43. $callback();
  44. return;
  45. }
  46. if ($this->lockInScope) {
  47. throw new PreConditionNotMetException('Could not obtain lock scope as already in use by ' . $this->lockInScope);
  48. }
  49. try {
  50. $this->lockInScope = $lock;
  51. $callback();
  52. } finally {
  53. $this->lockInScope = null;
  54. }
  55. }
  56. public function getLockInScope(): ?LockContext {
  57. return $this->lockInScope;
  58. }
  59. public function getLocks(int $fileId): array {
  60. if (!$this->getLockProvider()) {
  61. throw new PreConditionNotMetException('No lock provider available');
  62. }
  63. return $this->getLockProvider()->getLocks($fileId);
  64. }
  65. public function lock(LockContext $lockInfo): ILock {
  66. if (!$this->getLockProvider()) {
  67. throw new PreConditionNotMetException('No lock provider available');
  68. }
  69. return $this->getLockProvider()->lock($lockInfo);
  70. }
  71. public function unlock(LockContext $lockInfo): void {
  72. if (!$this->getLockProvider()) {
  73. throw new PreConditionNotMetException('No lock provider available');
  74. }
  75. $this->getLockProvider()->unlock($lockInfo);
  76. }
  77. }