/**
  * Runtime of Master process
  * @return void
  */
 public function run()
 {
     Daemon::$process = $this;
     $this->prepareSystemEnv();
     class_exists('Timer');
     // ensure loading this class
     gc_enable();
     $this->eventBase = event_base_new();
     $this->registerEventSignals();
     FS::initEvent();
     $this->fileWatcher = new FileWatcher();
     $this->workers = new ThreadCollection();
     $this->collections['workers'] = $this->workers;
     Daemon::$appResolver = (require Daemon::$config->path->value);
     $this->IPCManager = Daemon::$appResolver->getInstanceByAppName('IPCManager');
     Daemon::$appResolver->preload(true);
     $this->callbacks = new SplStack();
     $this->spawnWorkers(min(Daemon::$config->startworkers->value, Daemon::$config->maxworkers->value));
     Timer::add(function ($event) use(&$cbs) {
         $self = Daemon::$process;
         static $c = 0;
         ++$c;
         if ($c > 0xfffff) {
             $c = 1;
         }
         if ($c % 10 == 0) {
             $self->workers->removeTerminated(true);
             gc_collect_cycles();
         } else {
             $self->workers->removeTerminated();
         }
         if (isset(Daemon::$config->mpm->value) && is_callable(Daemon::$config->mpm->value)) {
             call_user_func(Daemon::$config->mpm->value);
         } else {
             // default MPM
             $state = Daemon::getStateOfWorkers($self);
             if ($state) {
                 $n = max(min(Daemon::$config->minspareworkers->value - $state['idle'], Daemon::$config->maxworkers->value - $state['alive']), Daemon::$config->minworkers->value - $state['alive']);
                 if ($n > 0) {
                     Daemon::log('Spawning ' . $n . ' worker(s).');
                     $self->spawnWorkers($n);
                     event_base_loopbreak($self->eventBase);
                 }
                 $n = min($state['idle'] - Daemon::$config->maxspareworkers->value, $state['alive'] - Daemon::$config->minworkers->value);
                 if ($n > 0) {
                     Daemon::log('Stopping ' . $n . ' worker(s).');
                     $self->stopWorkers($n);
                 }
             }
         }
         $event->timeout();
     }, 1000000.0 * Daemon::$config->mpmdelay->value, 'MPM');
     while (!$this->breakMainLoop) {
         while (!$this->callbacks->isEmpty()) {
             call_user_func($this->callbacks->shift(), $this);
         }
         event_base_loop($this->eventBase);
     }
 }
 /**
  * Runtime of Worker process.
  * @return void
  */
 public function run()
 {
     FS::init();
     Daemon::$process = $this;
     if (Daemon::$logpointerAsync) {
         $oldfd = Daemon::$logpointerAsync->fd;
         Daemon::$logpointerAsync->fd = null;
         Daemon::$logpointerAsync = null;
     }
     $this->autoReloadLast = time();
     $this->reloadDelay = Daemon::$config->mpmdelay->value + 2;
     $this->setStatus(4);
     if (Daemon::$config->autogc->value > 0) {
         gc_enable();
     } else {
         gc_disable();
     }
     $this->prepareSystemEnv();
     $this->overrideNativeFuncs();
     $this->setStatus(6);
     $this->eventBase = event_base_new();
     $this->registerEventSignals();
     FS::init();
     // re-init
     FS::initEvent();
     Daemon::openLogs();
     $this->fileWatcher = new FileWatcher();
     $this->IPCManager = Daemon::$appResolver->getInstanceByAppName('IPCManager');
     Daemon::$appResolver->preload();
     foreach (Daemon::$appInstances as $app) {
         foreach ($app as $appInstance) {
             if (!$appInstance->ready) {
                 $appInstance->ready = TRUE;
                 $appInstance->onReady();
             }
         }
     }
     $this->setStatus(1);
     Timer::add(function ($event) {
         $self = Daemon::$process;
         if ($self->checkState() !== TRUE) {
             $self->closeSockets();
             $self->breakMainLoop = TRUE;
             event_base_loopexit($self->eventBase);
             return;
         }
         $event->timeout();
     }, 1000000.0 * 1, 'checkState');
     if (Daemon::$config->autoreload->value > 0) {
         Timer::add(function ($event) {
             $self = Daemon::$process;
             static $n = 0;
             $inc = array_unique(array_map('realpath', get_included_files()));
             $s = sizeof($inc);
             if ($s > $n) {
                 $slice = array_slice($inc, $n);
                 Daemon::$process->IPCManager->sendPacket(array('op' => 'addIncludedFiles', 'files' => $slice));
                 $n = $s;
             }
             $event->timeout();
         }, 1000000.0 * Daemon::$config->autoreload->value, 'watchIncludedFiles');
     }
     while (!$this->breakMainLoop) {
         event_base_loop($this->eventBase);
     }
 }