--- a/multithreading.php Sun Jan 04 22:56:57 2009 -0500
+++ b/multithreading.php Tue May 26 15:24:26 2009 -0400
@@ -37,12 +37,13 @@
function Threader_SigUsr2()
{
- global $threader_instances;
+ global $threader_instances, $threader_notick;
+ if ( @$threader_notick )
+ return;
foreach ( $threader_instances as &$mt )
{
if ( is_object($mt) )
{
- $parchild = $mt->is_child() ? 'child' : 'parent';
$mt->event_sigusr2();
}
}
@@ -136,8 +137,8 @@
$threader_instances[] =& $this;
+ pcntl_signal(SIGCHLD, 'Threader_SigChld');
pcntl_signal(SIGUSR2, 'Threader_SigUsr2');
- pcntl_signal(SIGCHLD, 'Threader_SigChld');
}
$this->json = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
@@ -273,6 +274,7 @@
if ( $this->is_child() )
{
// this is easy - the parent sent the signal.
+ @stream_set_blocking($this->parent_sock, 0);
$command = rtrim(fgets($this->parent_sock, 102400), "\n");
}
else
@@ -281,8 +283,7 @@
// of time and try to read; if we get something, awesome.
foreach ( $this->ipc_sockets as $pid => $socket )
{
- // 1000 microseconds = 1/80th of the time it takes you to blink.
- @stream_set_timeout($socket, 0, 1000);
+ @stream_set_blocking($socket, 0);
$command = rtrim(@fgets($socket, 102400), "\n");
if ( !empty($command) )
{
--- a/webserver.php Sun Jan 04 22:56:57 2009 -0500
+++ b/webserver.php Tue May 26 15:24:26 2009 -0400
@@ -334,6 +334,7 @@
$this->server_string = "PhpHttpd/" . HTTPD_VERSION . " PHP/" . PHP_VERSION . "\r\n";
$this->parent_pid = getmypid();
$this->threader = new Threader();
+ $this->threader->ipc_register('ws_reboot', array(&$this, 'reboot'));
// create a UUID
$uuid_base = md5(microtime() . ( function_exists('mt_rand') ? mt_rand() : rand() ));
@@ -351,7 +352,7 @@
function __destruct()
{
- if ( !is_object($this->threader) )
+ if ( !$this->threader )
{
return false;
}
@@ -437,6 +438,10 @@
}
else if ( !$this->threader->is_child() && $oldfork )
{
+ // we are the parent and have been asked to respawn. there are (presumably)
+ // still children running around; when one of them dies, we'll receive a
+ // SIGCHLD, but often times this is already being called from the SIGUSR2
+ // handler. whoops.
if ( function_exists('status') )
status('Waiting on all children');
@@ -448,8 +453,7 @@
}
else
{
- // this is a childless parent; delay any action until the current
- // request has been sent (do nothing now)
+ // not sure what to do in this particular scenario.
}
}
@@ -578,7 +582,7 @@
{
if ( $start_time + HTTPD_KEEP_ALIVE_TIMEOUT < microtime(true) || $remote->is_eof() )
{
- // request expired -- end the process here
+ // request expired -- end the iteration here
if ( !$this->threader->is_child() )
$remote->destroy();
@@ -1256,7 +1260,8 @@
// $output = dechex(strlen($output)) . "\r\n$output";
// write body
- $socket->write($output);
+ if ( !empty($output) )
+ $socket->write($output);
$this->headers_sent = false;
}
@@ -2134,13 +2139,11 @@
function write($data)
{
- $data = str_split($data, 8096);
- foreach ( $data as $chunk )
+ $size = strlen($data);
+ $written = 0;
+ while ( $written < $size )
{
- while ( !@fwrite($this->sock, $chunk) )
- {
- usleep(50000);
- }
+ $written += @fwrite($this->sock, substr($data, $written));
}
return true;
}