Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- <?php
- interface Lock
- {
- public function release();
- }
- interface LockQueue
- {
- public function withLock(callable $callback): \Generator;
- public function getLock(): \Generator;
- }
- class SingleLockQueue implements LockQueue
- {
- /**
- * @var Deferred
- */
- private $last;
- public function withLock(callable $callback): \Generator
- {
- /** @var Lock $lock */
- $lock = yield from $this->getLock();
- try {
- $result = $callback();
- return $result instanceof \Generator ? yield from $result : $result;
- } finally {
- $lock->release();
- }
- }
- public function getLock(): \Generator
- {
- $deferred = new Deferred();
- $last = $this->last;
- $this->last = $deferred;
- if ($last !== null) {
- yield $last->promise();
- }
- return new class($deferred) implements Lock
- {
- private $deferred;
- private $released;
- public function __construct(Deferred $deferred = null)
- {
- $this->deferred = $deferred;
- }
- public function __destruct()
- {
- if (!$this->released) {
- $this->release();
- }
- }
- public function release()
- {
- if ($this->deferred !== null) {
- $this->deferred->succeed();
- }
- $this->released = true;
- }
- };
- }
- }
- $queue = new LockQueue;
- // usage:
- yield from $queue->withLock(function() {
- // do something that requires a lock on a particular resource
- });
- // or...
- $lock = yield from $queue->getLock();
- // do something that requires a lock on a particular resource
- $lock->release();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement