From 77a89b07d397ea8091c217bc1ab00c5c4b243009 Mon Sep 17 00:00:00 2001 From: erickson Date: Mon, 29 Nov 2010 19:19:02 +0000 Subject: [PATCH] add fault tolerance (e.g. recover from interrupted select/sysread); always perform idle maintenance when there are any active child processes; exit check status early when no active processes exist git-svn-id: svn://svn.open-ils.org/OpenSRF/branches/rel_2_0@2114 9efc2488-bf62-4759-914b-345cdb29e865 --- src/perl/lib/OpenSRF/Server.pm | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/src/perl/lib/OpenSRF/Server.pm b/src/perl/lib/OpenSRF/Server.pm index 0365783..9cce669 100644 --- a/src/perl/lib/OpenSRF/Server.pm +++ b/src/perl/lib/OpenSRF/Server.pm @@ -144,7 +144,9 @@ sub run { # when we hit equilibrium, there's no need for regular # maintenance, so set wait_time to 'forever' - $wait_time = -1 unless $self->perform_idle_maintenance; + $wait_time = -1 if + !$self->perform_idle_maintenance and # no maintenance performed this time + @{$self->{active_list}} == 0; # no active children } } } @@ -232,18 +234,31 @@ sub write_child { sub check_status { my($self, $block) = @_; + return unless @{$self->{active_list}}; + my $read_set = IO::Select->new; $read_set->add($_->{pipe_to_child}) for @{$self->{active_list}}; - my @handles = $read_set->can_read(($block) ? undef : 0) or return; - - my $pid = ''; my @pids; - for my $pipe (@handles) { - sysread($pipe, $pid, STATUS_PIPE_DATA_SIZE) or next; - push(@pids, int($pid)); + + while (1) { + + # if can_read or sysread is interrupted while bloking, go back and + # wait again until we have at least 1 free child + + if(my @handles = $read_set->can_read(($block) ? undef : 0)) { + my $pid = ''; + for my $pipe (@handles) { + sysread($pipe, $pid, STATUS_PIPE_DATA_SIZE) or next; + push(@pids, int($pid)); + } + } + + last unless $block and !@pids; } + return unless @pids; + $chatty and $logger->internal("server: ".scalar(@pids)." children reporting for duty: (@pids)"); my $child; @@ -276,7 +291,7 @@ sub reap_children { while(1) { my $pid = waitpid(-1, ($shutdown) ? 0 : WNOHANG); - return if $pid <= 0; + last if $pid <= 0; $chatty and $logger->internal("server: reaping child $pid"); -- 2.43.2