예제 #1
0
 /**
  * Runs the thread code and the initialized function.
  *
  * @codeCoverageIgnore Only executed in thread.
  */
 public function run()
 {
     /* First thing we need to do is re-initialize the class autoloader. If
      * we don't do this first, any object of a class that was loaded after
      * the thread started will just be garbage data and unserializable
      * values (like resources) will be lost. This happens even with
      * thread-safe objects.
      */
     foreach (get_declared_classes() as $className) {
         if (strpos($className, 'ComposerAutoloaderInit') === 0) {
             // Calling getLoader() will register the class loader for us
             $className::getLoader();
             break;
         }
     }
     Loop\loop($loop = Loop\create(false));
     // Disable signals in thread.
     // At this point, the thread environment has been prepared so begin using the thread.
     try {
         $channel = new ChannelledStream(new DuplexPipe($this->socket, false));
     } catch (\Throwable $exception) {
         return;
         // Parent has destroyed Thread object, so just exit.
     }
     $coroutine = new Coroutine($this->execute($channel));
     $coroutine->done();
     $timer = $loop->timer(self::KILL_CHECK_FREQUENCY, true, function () use($loop) {
         if ($this->killed) {
             $loop->stop();
         }
     });
     $timer->unreference();
     $loop->run();
 }
예제 #2
0
 /**
  * Starts the context execution.
  *
  * @throws \Icicle\Concurrent\Exception\ForkException If forking fails.
  * @throws \Icicle\Stream\Exception\FailureException If creating a socket pair fails.
  */
 public function start()
 {
     if (0 !== $this->oid) {
         throw new StatusError('The context has already been started.');
     }
     list($parent, $child) = Stream\pair();
     switch ($pid = pcntl_fork()) {
         case -1:
             // Failure
             throw new ForkException('Could not fork process!');
         case 0:
             // Child
             // @codeCoverageIgnoreStart
             // Create a new event loop in the fork.
             Loop\loop($loop = Loop\create(false));
             $channel = new ChannelledStream($pipe = new DuplexPipe($parent));
             fclose($child);
             $coroutine = new Coroutine($this->execute($channel));
             $coroutine->done();
             try {
                 $loop->run();
                 $code = 0;
             } catch (\Throwable $exception) {
                 $code = 1;
             }
             $pipe->close();
             exit($code);
             // @codeCoverageIgnoreEnd
         // @codeCoverageIgnoreEnd
         default:
             // Parent
             $this->pid = $pid;
             $this->oid = posix_getpid();
             $this->channel = new ChannelledStream($this->pipe = new DuplexPipe($child));
             fclose($parent);
     }
 }
예제 #3
0
 /**
  * @param \Icicle\Loop\Loop|null $loop
  */
 public function __construct(Loop\Loop $loop = null)
 {
     $this->loop = $loop ?: Loop\loop();
 }
 public function setUp()
 {
     Loop\loop(new Loop\SelectLoop());
 }