Ejemplo n.º 1
0
 public function __construct($name, $pid, Error $error = null)
 {
     $this->name = $name;
     $this->pid = $pid;
     $this->error = $error;
     if ($error) {
         if (__CLASS__ === $error->getClass()) {
             parent::__construct(sprintf('%s via "%s" fork (%d)', $error->getMessage(), $name, $pid));
         } else {
             parent::__construct(sprintf('%s (%d) thrown in "%s" fork (%d): "%s" (%s:%d)', $error->getClass(), $error->getCode(), $name, $pid, $error->getMessage(), $error->getFile(), $error->getLine()));
         }
     } else {
         parent::__construct(sprintf('An unknown error occurred in "%s" fork (%d)', $name, $pid));
     }
 }
Ejemplo n.º 2
0
 /**
  * Forks something into another process and returns a deferred object.
  * @param $callable
  * @param string $processTitle
  * @return Fork
  */
 public function fork($callable, $processTitle = null)
 {
     if (!is_callable($callable)) {
         throw new UnexpectedTypeException($callable, 'callable');
     }
     // allow the system to cleanup before forking
     $this->dispatcher->dispatch(Events::PRE_FORK);
     if (-1 === ($pid = pcntl_fork())) {
         throw new ProcessControlException('Unable to fork a new process');
     }
     if (0 === $pid) {
         if (function_exists('cli_set_process_title') && $processTitle !== null) {
             cli_set_process_title($processTitle);
         }
         // reset the list of child processes
         $this->forks = array();
         // setup the shared memory
         $shm = $this->factory->createSharedMemory(null, $this->signal);
         $message = new ExitMessage();
         // phone home on shutdown
         register_shutdown_function(function () use($shm, $message) {
             $status = null;
             try {
                 $shm->send($message, false);
             } catch (\Exception $e) {
                 // probably an error serializing the result
                 $message->setResult(null);
                 $message->setError(Error::fromException($e));
                 $shm->send($message, false);
                 exit(2);
             }
         });
         // dispatch an event so the system knows it's in a new process
         $this->dispatcher->dispatch(Events::POST_FORK);
         if (!$this->debug) {
             ob_start();
         }
         try {
             $result = call_user_func($callable, $shm);
             $message->setResult($result);
             $status = is_integer($result) ? $result : 0;
         } catch (\Exception $e) {
             $message->setError(Error::fromException($e));
             $status = 1;
         }
         if (!$this->debug) {
             $message->setOutput(ob_get_clean());
         }
         exit($status);
     }
     // connect to shared memory
     $shm = $this->factory->createSharedMemory($pid);
     return $this->forks[$pid] = $this->factory->createFork($pid, $shm, $this->debug);
 }