tcpserver : work correctely with the loopInBackgroundStart / Stop
git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@5975 bf3deb0d-5f1a-0410-827f-c0cc1f45334c
This commit is contained in:
@@ -56,11 +56,24 @@ class tcpserver
|
||||
/** The number of active clients
|
||||
*/
|
||||
private $nbChild = 0;
|
||||
/** The PID number when loop in background is active
|
||||
*/
|
||||
private $pidLoopInBackground;
|
||||
/** Server name displayed in process list
|
||||
*/
|
||||
private $processName;
|
||||
// }}}
|
||||
|
||||
////////////////////////
|
||||
// PUBLIC METHODS //
|
||||
////////////////////////
|
||||
public function __construct ()
|
||||
// {{{
|
||||
{
|
||||
$this->processName = "tcpserver";
|
||||
}
|
||||
// }}}
|
||||
|
||||
/** Set/get the max children, the maximum of concurrent connections
|
||||
* @param integer|null $val The number of child to get/set
|
||||
*/
|
||||
@@ -90,6 +103,18 @@ class tcpserver
|
||||
}
|
||||
// }}}
|
||||
|
||||
/** Set the process name displayed in system
|
||||
*/
|
||||
public function processName ($val = null)
|
||||
// {{{
|
||||
{
|
||||
if ($val === null)
|
||||
return $this->processName;
|
||||
$this->processName = $val;
|
||||
return $this;
|
||||
}
|
||||
// }}}
|
||||
|
||||
/** Set the address, port and handler that will be enabled by loop
|
||||
* @param string $address The server address (can be 0.0.0.0 for all IPv4
|
||||
* interfaces or :: for all the IPv4 and IPv6 interfaces)
|
||||
@@ -118,6 +143,7 @@ class tcpserver
|
||||
pcntl_signal (SIGCHLD,[$this, "sigCHLD"]);
|
||||
pcntl_signal (SIGTERM,[$this, "sigTERMINT"]);
|
||||
pcntl_signal (SIGINT,[$this, "sigTERMINT"]);
|
||||
cli_set_process_title ($this->processName." main");
|
||||
foreach ($this->addresses as $key => $address)
|
||||
{
|
||||
$port = $this->ports[$key];
|
||||
@@ -137,8 +163,14 @@ class tcpserver
|
||||
printf ("[".posix_getpid ()."] Listening on %s:%d...\n",
|
||||
$address, $port);
|
||||
}
|
||||
$ppid = posix_getppid ();
|
||||
while (1)
|
||||
{
|
||||
if (posix_getppid () !== $ppid)
|
||||
{
|
||||
echo "PARENT PID change : ".posix_getppid () ."!== $ppid : STOP\n";
|
||||
$this->loopStop ();
|
||||
}
|
||||
if ($this->loopStop)
|
||||
{
|
||||
if ($this->debug)
|
||||
@@ -229,6 +261,7 @@ class tcpserver
|
||||
echo "[".posix_getpid ()."] Child start ($address:$port) : ".
|
||||
($this->nbChild+1)." child active\n";
|
||||
// Do not stop if the parent is requesting a stop from Ctrl+C
|
||||
cli_set_process_title ($this->processName." ($address:$port)");
|
||||
pcntl_signal(SIGINT, SIG_IGN);
|
||||
$sid = posix_setsid();
|
||||
// In the child. Will call the handler with the actual tcpserver object
|
||||
@@ -248,7 +281,7 @@ class tcpserver
|
||||
}
|
||||
if ($this->debug)
|
||||
echo "[".posix_getpid ()."] Child ended ($address:$port)\n";
|
||||
return;
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -268,20 +301,25 @@ class tcpserver
|
||||
/** Start the main loop in background and do not wait its end
|
||||
* @return the PID of the child
|
||||
*/
|
||||
public function loopInBackground ()
|
||||
public function loopInBackgroundStart ()
|
||||
// {{{
|
||||
{
|
||||
if ($this->debug)
|
||||
echo "[".posix_getpid ()."] Start loopInBackground\n";
|
||||
$pid = pcntl_fork();
|
||||
$this->pidLoopInBackground = $pid;
|
||||
if ($pid == -1)
|
||||
{
|
||||
throw new \Exception ("TCPServer can not fork in background", 500);
|
||||
}
|
||||
else if ($pid)
|
||||
{
|
||||
if ($this->debug)
|
||||
echo "[".posix_getpid ()."] loopInBackground : child = ".
|
||||
$this->pidLoopInBackground."\n";
|
||||
// parent process: return to the main loop
|
||||
return $pid;
|
||||
}
|
||||
echo "CHILD";
|
||||
$sid = posix_setsid();
|
||||
// Will catch all the text messages from the application to not crash if
|
||||
// there is an "echo"
|
||||
@@ -289,9 +327,20 @@ echo "CHILD";
|
||||
@fclose (STDIN);
|
||||
@fclose (STDOUT);
|
||||
@fclose (STDERR);
|
||||
echo "IN";
|
||||
$this->loop ();
|
||||
return;
|
||||
exit;
|
||||
}
|
||||
// }}}
|
||||
|
||||
/** Stop the main loop in background and wait until its end
|
||||
*/
|
||||
public function loopInBackgroundStop ()
|
||||
// {{{
|
||||
{
|
||||
if ($this->debug)
|
||||
echo "[".posix_getpid ()."] Request loopInBackgroundStop\n";
|
||||
posix_kill ($this->pidLoopInBackground, SIGINT);
|
||||
pcntl_waitpid ($this->pidLoopInBackground, $status);
|
||||
}
|
||||
// }}}
|
||||
|
||||
@@ -450,7 +499,9 @@ echo "IN";
|
||||
if ($this->debug)
|
||||
echo "[".posix_getpid ()."] One child finished : $this->nbChild childs ".
|
||||
"remain active\n";
|
||||
pcntl_wait ($status, WNOHANG);
|
||||
//pcntl_wait ($status, WNOHANG);
|
||||
$rc = pcntl_wait ($status);
|
||||
echo "END : rc\n";
|
||||
}
|
||||
// }}}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user