webserver.php
changeset 68 32f6e2ee15ab
parent 67 c4aefad02ce4
child 76 487a16c7117c
equal deleted inserted replaced
67:c4aefad02ce4 68:32f6e2ee15ab
   332     $this->bind_address = $address;
   332     $this->bind_address = $address;
   333     $this->port = $port;
   333     $this->port = $port;
   334     $this->server_string = "PhpHttpd/" . HTTPD_VERSION . " PHP/" . PHP_VERSION . "\r\n";
   334     $this->server_string = "PhpHttpd/" . HTTPD_VERSION . " PHP/" . PHP_VERSION . "\r\n";
   335     $this->parent_pid = getmypid();
   335     $this->parent_pid = getmypid();
   336     $this->threader = new Threader();
   336     $this->threader = new Threader();
       
   337     $this->threader->ipc_register('ws_reboot', array(&$this, 'reboot'));
   337     
   338     
   338     // create a UUID
   339     // create a UUID
   339     $uuid_base = md5(microtime() . ( function_exists('mt_rand') ? mt_rand() : rand() ));
   340     $uuid_base = md5(microtime() . ( function_exists('mt_rand') ? mt_rand() : rand() ));
   340     $this->uuid = substr($uuid_base, 0,  8) . '-' .
   341     $this->uuid = substr($uuid_base, 0,  8) . '-' .
   341                   substr($uuid_base, 8,  4) . '-' .
   342                   substr($uuid_base, 8,  4) . '-' .
   349    * Destructor.
   350    * Destructor.
   350    */
   351    */
   351   
   352   
   352   function __destruct()
   353   function __destruct()
   353   {
   354   {
   354     if ( !is_object($this->threader) )
   355     if ( !$this->threader )
   355     {
   356     {
   356       return false;
   357       return false;
   357     }
   358     }
   358     if ( !$this->threader->is_child() && $this->socket_initted )
   359     if ( !$this->threader->is_child() && $this->socket_initted )
   359     {
   360     {
   435         'fork' => $fork
   436         'fork' => $fork
   436       ));
   437       ));
   437     }
   438     }
   438     else if ( !$this->threader->is_child() && $oldfork )
   439     else if ( !$this->threader->is_child() && $oldfork )
   439     {
   440     {
       
   441       // we are the parent and have been asked to respawn. there are (presumably)
       
   442       // still children running around; when one of them dies, we'll receive a
       
   443       // SIGCHLD, but often times this is already being called from the SIGUSR2
       
   444       // handler. whoops.
   440       if ( function_exists('status') )
   445       if ( function_exists('status') )
   441         status('Waiting on all children');
   446         status('Waiting on all children');
   442       
   447       
   443       // this is the parent, and there are children present
   448       // this is the parent, and there are children present
   444       $this->threader->kill_all_children();
   449       $this->threader->kill_all_children();
   446       // all children are dead, we are ok to respawn
   451       // all children are dead, we are ok to respawn
   447       $this->respawn();
   452       $this->respawn();
   448     }
   453     }
   449     else
   454     else
   450     {
   455     {
   451       // this is a childless parent; delay any action until the current
   456       // not sure what to do in this particular scenario.
   452       // request has been sent (do nothing now)
       
   453     }
   457     }
   454   }
   458   }
   455   
   459   
   456   /**
   460   /**
   457    * Respawns the server. All children should be dead, and any client
   461    * Respawns the server. All children should be dead, and any client
   576       $last_line = '';
   580       $last_line = '';
   577       while ( true )
   581       while ( true )
   578       {
   582       {
   579         if ( $start_time + HTTPD_KEEP_ALIVE_TIMEOUT < microtime(true) || $remote->is_eof() )
   583         if ( $start_time + HTTPD_KEEP_ALIVE_TIMEOUT < microtime(true) || $remote->is_eof() )
   580         {
   584         {
   581           // request expired -- end the process here
   585           // request expired -- end the iteration here
   582           if ( !$this->threader->is_child() )
   586           if ( !$this->threader->is_child() )
   583             $remote->destroy();
   587             $remote->destroy();
   584           
   588           
   585           continue 2;
   589           continue 2;
   586         }
   590         }
  1254           
  1258           
  1255           // chunk output
  1259           // chunk output
  1256           // $output = dechex(strlen($output)) . "\r\n$output";
  1260           // $output = dechex(strlen($output)) . "\r\n$output";
  1257           
  1261           
  1258           // write body
  1262           // write body
  1259           $socket->write($output);
  1263           if ( !empty($output) )
       
  1264             $socket->write($output);
  1260           
  1265           
  1261           $this->headers_sent = false;
  1266           $this->headers_sent = false;
  1262         }
  1267         }
  1263         
  1268         
  1264         break;
  1269         break;
  2132     $port = substr($peer, strrpos($peer, ':') + 1);
  2137     $port = substr($peer, strrpos($peer, ':') + 1);
  2133   }
  2138   }
  2134   
  2139   
  2135   function write($data)
  2140   function write($data)
  2136   {
  2141   {
  2137     $data = str_split($data, 8096);
  2142     $size = strlen($data);
  2138     foreach ( $data as $chunk )
  2143     $written = 0;
  2139     {
  2144     while ( $written < $size )
  2140       while ( !@fwrite($this->sock, $chunk) )
  2145     {
  2141       {
  2146       $written += @fwrite($this->sock, substr($data, $written));
  2142         usleep(50000);
       
  2143       }
       
  2144     }
  2147     }
  2145     return true;
  2148     return true;
  2146   }
  2149   }
  2147   
  2150   
  2148   function is_eof()
  2151   function is_eof()