Advertisement
Guest User

Untitled

a guest
Apr 30th, 2016
155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 1.84 KB | None | 0 0
  1. <?php
  2.  
  3. interface Lock
  4. {
  5.     public function release();
  6. }
  7.  
  8. interface LockQueue
  9. {
  10.     public function withLock(callable $callback): \Generator;
  11.     public function getLock(): \Generator;
  12. }
  13.  
  14. class SingleLockQueue implements LockQueue
  15. {
  16.     /**
  17.      * @var Deferred
  18.      */
  19.     private $last;
  20.  
  21.     public function withLock(callable $callback): \Generator
  22.     {
  23.         /** @var Lock $lock */
  24.         $lock = yield from $this->getLock();
  25.  
  26.         try {
  27.             $result = $callback();
  28.             return $result instanceof \Generator ? yield from $result : $result;
  29.         } finally {
  30.             $lock->release();
  31.         }
  32.     }
  33.  
  34.     public function getLock(): \Generator
  35.     {
  36.         $deferred = new Deferred();
  37.         $last = $this->last;
  38.  
  39.         $this->last = $deferred;
  40.  
  41.         if ($last !== null) {
  42.             yield $last->promise();
  43.         }
  44.  
  45.         return new class($deferred) implements Lock
  46.         {
  47.             private $deferred;
  48.  
  49.             private $released;
  50.  
  51.             public function __construct(Deferred $deferred = null)
  52.             {
  53.                 $this->deferred = $deferred;
  54.             }
  55.  
  56.             public function __destruct()
  57.             {
  58.                 if (!$this->released) {
  59.                     $this->release();
  60.                 }
  61.             }
  62.  
  63.             public function release()
  64.             {
  65.                 if ($this->deferred !== null) {
  66.                     $this->deferred->succeed();
  67.                 }
  68.  
  69.                 $this->released = true;
  70.             }
  71.         };
  72.     }
  73. }
  74.  
  75. $queue = new LockQueue;
  76.  
  77. // usage:
  78. yield from $queue->withLock(function() {
  79.     // do something that requires a lock on a particular resource
  80. });
  81.  
  82. // or...
  83. $lock = yield from $queue->getLock();
  84. // do something that requires a lock on a particular resource
  85. $lock->release();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement