Diff for /loncom/lonmaxima between versions 1.13 and 1.15

version 1.13, 2006/03/08 12:57:30 version 1.15, 2006/03/08 15:58:03
Line 37  use IO::Socket; Line 37  use IO::Socket;
 use IO::File;  use IO::File;
 use Symbol;  use Symbol;
 use POSIX;  use POSIX;
 use Fcntl;  
 use Socket;  
 use lib '/home/httpd/lib/perl/';  use lib '/home/httpd/lib/perl/';
 use LONCAPA::Configuration;  use LONCAPA::Configuration;
     
Line 65  sub REAPER {                        # ta Line 63  sub REAPER {                        # ta
     $SIG{CHLD} = \&REAPER;      $SIG{CHLD} = \&REAPER;
     my $pid = wait;      my $pid = wait;
     $children--;      $children--;
       &logthis("Child $pid for port or process $children{$pid} died");
     delete($usedmaximaports{$children{$pid}});      delete($usedmaximaports{$children{$pid}});
     delete($children{$pid});      delete($children{$pid});
 }  }
Line 130  sub catchexception { Line 129  sub catchexception {
     die("Signal abend");      die("Signal abend");
 }  }
   
 # -------------------------------------------------- make a socket non-blocking  
 sub nonblock {  
     my $socket = shift;  
     my $flags;  
     if (ref($socket)) {   
        $flags = fcntl($socket, F_GETFL, 0)  
             or die "Can't get flags for socket: $!\n";  
        fcntl($socket, F_SETFL, $flags | O_NONBLOCK)  
             or die "Can't make socket nonblocking: $!\n";  
     }  
 }  
   
 # ---------------------------------------------------------------- Main program  # ---------------------------------------------------------------- Main program
 # -------------------------------- Set signal handlers to record abnormal exits  # -------------------------------- Set signal handlers to record abnormal exits
     
Line 232  while (1) { Line 219  while (1) {
     for (my $i = $children; $i < $PREFORK; $i++) {      for (my $i = $children; $i < $PREFORK; $i++) {
         &status('Parent process, starting child');          &status('Parent process, starting child');
         my $newport;          my $newport;
         foreach $newport ($STARTPORT .. $STARTPORT+$PREFORK-1) {          &logthis("Current pool: ".join(', ',keys %usedmaximaports));
             if (!defined($usedmaximaports{$newport})) { last; }          foreach my $testport ($STARTPORT .. $STARTPORT+$PREFORK-1) {
               if (!$usedmaximaports{$testport}) { $newport=$testport; }
           }
           if ($newport) {
              &make_new_child($server,$newport);           # top up the child pool
         }          }
         &make_new_child($server,$newport);           # top up the child pool  
     }      }
 }  }
                                                                                                                                                                   
Line 255  sub make_new_child { Line 245  sub make_new_child {
             or die("Can't unblock SIGINT for fork: $!\n");              or die("Can't unblock SIGINT for fork: $!\n");
         $children{$pid} = $maximaport;          $children{$pid} = $maximaport;
         $children++;          $children++;
           $usedmaximaports{$maximaport}=1;
         return;          return;
     } else {      } else {
           &logthis("Starting child on port $maximaport");
         # Child can *not* return from this subroutine.          # Child can *not* return from this subroutine.
         $SIG{INT} = 'DEFAULT';      # make SIGINT kill us as it did before          $SIG{INT} = 'DEFAULT';      # make SIGINT kill us as it did before
             
Line 271  sub make_new_child { Line 263  sub make_new_child {
                                               Reuse     => 1,                                                Reuse     => 1,
                                               Listen    => 10 )                                                Listen    => 10 )
                         or die "making socket: $@\n";                          or die "making socket: $@\n";
         &nonblock($maximaserver);  
         my $maximaselect=IO::Select->new($maximaserver);          my $maximaselect=IO::Select->new($maximaserver);
           sleep(1);
   
         # open MAXIMA to talk to that port          # open MAXIMA to talk to that port
         my ($cmd_in, $cmd_out, $cmd_err);          my ($cmd_in, $cmd_out, $cmd_err);
         my $maximapid = open3($cmd_in, $cmd_out, $cmd_err, "maxima -s $maximaport");          my $maximapid = open3($cmd_in, $cmd_out, $cmd_err, "maxima -s $maximaport");
         $children{$maximapid} = 1;          $children{$maximapid} = "Maxima $maximapid port $maximaport";
         my $prompt=<$cmd_out>;          my $prompt=<$cmd_out>;
         &logthis("Maxima $maximapid: $prompt");          &logthis("Maxima $maximapid: $prompt");
   
         # hopefully, MAXIMA calls us back          # hopefully, MAXIMA calls us back
         &status("Waiting $maximapid on $maximaport");          &status("Waiting $maximapid on $maximaport");
         my $maximaclient=$maximaserver->accept();          my $maximaclient=$maximaserver->accept();
           $maximaclient->blocking(0);
         $maximaselect->add($maximaclient);          $maximaselect->add($maximaclient);
         &nonblock($maximaclient);  
         &status("$maximapid on $maximaport connected.");          &status("$maximapid on $maximaport connected.");
         &logthis("Maxima $maximapid on port $maximaport connected.");          &logthis("Maxima $maximapid on port $maximaport connected.");
           sleep(2);
   
         &logthis('Initial reply: '.&maximareply($maximaselect));          &logthis('Initial reply: '.&maximareply($maximaselect));
         # handle connections until we've reached $MAX_CLIENTS_PER_CHILD          # handle connections until we've reached $MAX_CLIENTS_PER_CHILD
         for (my $i=0; $i < $MAX_CLIENTS_PER_CHILD; $i++) {          for (my $i=0; $i < $MAX_CLIENTS_PER_CHILD; $i++) {
Line 295  sub make_new_child { Line 289  sub make_new_child {
             my $client = $server->accept()     or last;              my $client = $server->accept()     or last;
             while (my $cmd=<$client>) {              while (my $cmd=<$client>) {
                 &status('Processing command by '.$maximapid.' on '.$maximaport);                  &status('Processing command by '.$maximapid.' on '.$maximaport);
                 print $maximaclient &unescape($cmd).";\n";                  &maximawrite($maximaselect,&unescape($cmd).";\n");
                 print $client &escape(&maximareply($maximaselect))."\n";                  print $client &escape(&maximareply($maximaselect))."\n";
             }              }
         }          }
Line 316  sub make_new_child { Line 310  sub make_new_child {
 sub maximareply {  sub maximareply {
    my ($maximaselect)=@_;     my ($maximaselect)=@_;
    my $output='';     my $output='';
      
    foreach my $ready ($maximaselect->can_read(1)) {     foreach my $ready ($maximaselect->can_read(1)) {
        my $data = '';         my $data = '';
        my $rv   = $ready->recv($data, POSIX::BUFSIZ, 0);         my $rv   = $ready->recv($data, POSIX::BUFSIZ, 0);
Line 324  sub maximareply { Line 319  sub maximareply {
    return $output;     return $output;
 }  }
   
   sub maximawrite {
      my ($maximaselect,$cmd)=@_;
      my $ready=($maximaselect->can_write(1));
      if (ref($ready)) {
         print $ready $cmd;
      } else {
         &logthis("Cannot write: ".&maximareply($maximaselect));
      }
   }
   
   

Removed from v.1.13  
changed lines
  Added in v.1.15


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>