diff --git a/tcpserver.php b/tcpserver.php index 0d50ea4..fd9acab 100644 --- a/tcpserver.php +++ b/tcpserver.php @@ -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"; } // }}}