binkp_active) $start->put('binkp',[ 'address'=>$o->binkp_bind, 'port'=>$o->binkp_port, 'proto'=>SOCK_STREAM, 'class'=>new Binkp($o), ]); if ($o->emsi_active) $start->put('emsi',[ 'address'=>$o->emsi_bind, 'port'=>$o->emsi_port, 'proto'=>SOCK_STREAM, 'class'=>new EMSI($o), ]); if ($o->dns_active) $start->put('dns',[ 'address'=>$o->dns_bind, 'port'=>$o->dns_port, 'proto'=>SOCK_DGRAM, 'class'=>new DNS(), ]); $children = collect(); Log::debug(sprintf('%s:# Servers [%d]',self::LOGKEY,$start->count())); if (! $start->count()) { Log::alert(sprintf('%s:! No servers configured to start',self::LOGKEY)); return; } pcntl_signal(SIGCHLD,SIG_IGN); foreach ($start as $item => $config) { Log::debug(sprintf('%s:- Starting [%s] (%d)',self::LOGKEY,$item,getmypid())); $pid = pcntl_fork(); if ($pid === -1) die('could not fork'); // We are the child if (! $pid) { Log::withContext(['pid'=>getmypid()]); Log::info(sprintf('%s:= Started [%s]',self::LOGKEY,$item)); $server = new SocketServer($config['port'],$config['address'],$config['proto']); $server->handler = [$config['class'],'onConnect']; try { $server->listen(); } catch (SocketException $e) { if ($e->getMessage() === 'Can\'t accept connections: "Success"') Log::debug(sprintf('%s:! Server Terminated [%s]',self::LOGKEY,$item)); else Log::emergency(sprintf('%s:! Uncaught Message: %s',self::LOGKEY,$e->getMessage())); } Log::info(sprintf('%s:= Finished: [%s]',self::LOGKEY,$item)); // Child finished we need to get out of this loop. exit; } Log::debug(sprintf('%s:- Forked for [%s] (%d)',self::LOGKEY,$item,$pid)); $children->put($pid,$item); } // Wait for children to exit while ($x=$children->count()) { // Wait for children to finish $exited = pcntl_wait($status); if ($exited < 0) abort(500,'Something strange for status: '.serialize($status)); Log::info(sprintf('%s:= Exited: #%d [%s]',self::LOGKEY,$x,$children->pull($exited))); } // Done Log::debug(sprintf('%s:= Finished.',self::LOGKEY)); } }