Diff for /loncom/lonmaxima between versions 1.12 and 1.15

version 1.12, 2006/03/08 03:18:42 version 1.15, 2006/03/08 15:58:03
Line 57  my $lastlog;                           # Line 57  my $lastlog;                           #
 use vars qw($PREFORK $MAX_CLIENTS_PER_CHILD %children $children %usedmaximaports $status  use vars qw($PREFORK $MAX_CLIENTS_PER_CHILD %children $children %usedmaximaports $status
     $pidfile $port %perlvar $lastlog);      $pidfile $port %perlvar $lastlog);
     
 sub maximareply {  
     my ($cmd,$maximaclient,$maximapid) = @_;  
     my $reply='';  
     while (my $line=<$maximaclient>) {  
        $reply.=$line;  
     }  
     unless ($cmd=~/\;\n$/) { $cmd.=";\n"; }  
     print $maximaclient $cmd;  
     &status("Command sent to $maximapid");  
     while (my $line=<$maximaclient>) {  
        $reply.=$line;  
     }  
     &status("Command processed by $maximapid");  
     return $reply;  
 }  
    
 # ------------------------------------------------------------ Service routines   # ------------------------------------------------------------ Service routines 
 sub REAPER {                        # takes care of dead children   sub REAPER {                        # takes care of dead children 
                                     # and MAXIMA processes                                      # and MAXIMA processes
     $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 144  sub catchexception { Line 129  sub catchexception {
     die("Signal abend");      die("Signal abend");
 }  }
   
   
   
 # ---------------------------------------------------------------- Main program  # ---------------------------------------------------------------- Main program
 # -------------------------------- Set signal handlers to record abnormal exits  # -------------------------------- Set signal handlers to record abnormal exits
     
Line 236  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 259  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 275  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";
           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
         &status("Waiting $maximapid on $maximaport");          &status("Waiting $maximapid on $maximaport");
         # Hopefully, MAXIMA calls us back  
         my $maximaclient=$maximaserver->accept();          my $maximaclient=$maximaserver->accept();
           $maximaclient->blocking(0);
           $maximaselect->add($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);
   
         # Absorb initial prompts               &logthis('Initial reply: '.&maximareply($maximaselect));
         &logthis(&maximareply("0;\n",$maximaclient,$maximapid));          # handle connections until we've reached $MAX_CLIENTS_PER_CHILD
            for (my $i=0; $i < $MAX_CLIENTS_PER_CHILD; $i++) {
         # Ready for action                &status('Accepting connections for '.$maximapid.' on '.$maximaport);
               my $client = $server->accept()     or last;
         &process_requests($server,$maximaclient,$maximapid);              while (my $cmd=<$client>) {
                   &status('Processing command by '.$maximapid.' on '.$maximaport);
                   &maximawrite($maximaselect,&unescape($cmd).";\n");
                   print $client &escape(&maximareply($maximaselect))."\n";
               }
           }
   
         # tidy up gracefully and finish          # tidy up gracefully and finish
   
Line 310  sub make_new_child { Line 307  sub make_new_child {
     }      }
 }  }
   
 sub process_requests {  sub maximareply {
     my ($server,$maximaclient,$maximapid) = @_;     my ($maximaselect)=@_;
     # handle connections until we've reached $MAX_CLIENTS_PER_CHILD     my $output='';
     for (my $i=0; $i < $MAX_CLIENTS_PER_CHILD; $i++) {     
  &status('Accepting connections for '.$maximapid.' on '.$maximaport);          foreach my $ready ($maximaselect->can_read(1)) {
  my $client = $server->accept()     or last;         my $data = '';
  while (my $cmd=<$client>) {         my $rv   = $ready->recv($data, POSIX::BUFSIZ, 0);
     &status('Processing command by '.$maximapid.' on '.$maximaport);         $output.=$data;
     print $client &escape((&maximareply(&unescape($cmd),$maximaclient,$maximapid))[0])."\n";     }
  }     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.12  
changed lines
  Added in v.1.15


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