예제 #1
0
파일: UvLoop.php 프로젝트: koolkode/async
 /**
  * Executes libuv callbacks and ensures that the loop keeps running until the callback has been invoked.
  * 
  * Arguments must contain 1 closure that is assumed to be the callback being invoked by libuv.
  * 
  * @param string $func The name of the uv function to be called.
  * @param mixed $args Arguments to be passed to the function.
  * @return mixed Value returned / error thrown by the passed callback.
  * 
  * @throws \InvalidArgumentException When no callback argument has been passed.
  */
 public function handleCallback(string $func, ...$args) : Awaitable
 {
     $defer = new Deferred();
     $defer->when(function () {
         $this->watchersReferenced--;
     });
     for ($len = \count($args), $i = 0; $i < $len; $i++) {
         if ($args[$i] instanceof \Closure) {
             $callback = $args[$i];
             $args[$i] = function (...$args) use($defer, $callback) {
                 try {
                     $result = $callback(...$args);
                 } catch (\Throwable $e) {
                     return $defer->fail($e);
                 }
                 if ($result instanceof \Generator) {
                     $defer->resolve(new Coroutine($result));
                 } else {
                     $defer->resolve($result);
                 }
             };
             break;
         }
     }
     if (!isset($callback)) {
         return new Failure(new \InvalidArgumentException('Missing callback argument'));
     }
     $this->watchersReferenced++;
     try {
         $func(...\array_merge([$this->loop], $args));
     } catch (\Throwable $e) {
         $this->watchersReferenced--;
         return new Failure($e);
     }
     return $defer;
 }
예제 #2
0
 public function handleCallback(string $func, ...$args) : Awaitable
 {
     $request = null;
     $defer = new Deferred(function () use(&$request) {
         if (\is_resource($request)) {
             \eio_cancel($request);
         }
     });
     $defer->when(function () {
         $this->pending--;
         if (!$this->pending) {
             Loop::disable($this->watcherId);
         }
     });
     for ($len = \count($args), $i = 0; $i < $len; $i++) {
         if ($args[$i] instanceof \Closure) {
             $callback = $args[$i];
             $args[$i] = function (...$args) use($defer, $callback) {
                 try {
                     $result = $callback(...$args);
                 } catch (\Throwable $e) {
                     return $defer->fail($e);
                 }
                 if ($result instanceof \Generator) {
                     $defer->resolve(new Coroutine($result));
                 } else {
                     $defer->resolve($result);
                 }
             };
             break;
         }
     }
     if (!isset($callback)) {
         throw new \InvalidArgumentException('Missing callback argument');
     }
     if (!$this->pending) {
         if ($this->watcherId === null) {
             $this->watcherId = Loop::onReadable(self::$eio, self::$callback);
         } else {
             Loop::enable($this->watcherId);
         }
     }
     $this->pending++;
     try {
         $request = $func(...$args);
     } catch (\Throwable $e) {
         $this->pending--;
         if (!$this->pending) {
             Loop::disable($this->watcherId);
         }
         return new Failure($e);
     }
     return $defer;
 }