/**
* Runtime of Master process
* @return void
*/
protected function run()
{
Daemon::$process = $this;
$this->prepareSystemEnv();
class_exists('Timer');
// ensure loading this class
gc_enable();
/* This line must be commented according to current libevent binding implementation. May be uncommented in future. */
//$this->eventBase = new \EventBase;
if ($this->eventBase) {
$this->registerEventSignals();
} else {
$this->registerSignals();
}
$this->workers = new Collection();
$this->collections['workers'] = $this->workers;
$this->ipcthreads = new Collection();
$this->collections['ipcthreads'] = $this->ipcthreads;
Daemon::$appResolver->preload(true);
$this->callbacks = new StackCallbacks();
$this->spawnIPCThread();
$this->spawnWorkers(min(Daemon::$config->startworkers->value, Daemon::$config->maxworkers->value));
$this->timerCb = function ($event) use(&$cbs) {
static $c = 0;
++$c;
if ($c > 0xfffff) {
$c = 1;
}
if ($c % 10 == 0) {
gc_collect_cycles();
}
if (!$this->lastMpmActionTs || microtime(true) - $this->lastMpmActionTs > $this->minMpmActionInterval) {
$this->callMPM();
}
if ($event) {
$event->timeout();
}
};
if ($this->eventBase) {
// we are using libevent in Master
Timer::add($this->timerCb, 1000000.0 * Daemon::$config->mpmdelay->value, 'MPM');
while (!$this->breakMainLoop) {
$this->callbacks->executeAll($this);
if (!$this->eventBase->dispatch()) {
break;
}
}
} else {
// we are NOT using libevent in Master
$lastTimerCall = microtime(true);
while (!$this->breakMainLoop) {
$this->callbacks->executeAll($this);
if (microtime(true) > $lastTimerCall + Daemon::$config->mpmdelay->value) {
call_user_func($this->timerCb, null);
$lastTimerCall = microtime(true);
}
$this->sigwait();
}
}
}