my($self, $child, $msg) = @_;
my $xml = encode_utf8(decode_utf8($msg->to_xml));
+ # XXX: LP#1697029
+ # Inspect $child first to confirm its initial state.
+ # $child will stringify to its PID.
+ my $run_away = 0;
+ if ($child) {
+
+ if ($child->{dead}) {
+ $run_away = 1;
+ $logger->error("server: child $child is dead in write_child()");
+
+ } elsif (!$child->{pipe_to_child}) {
+ $run_away = 1;
+ $logger->error("server: pipe_to_child is undef for child ".
+ "$child (num_requests=".$child->{num_requests});
+ }
+ } else {
+ $run_away = 1;
+ $logger->error("server: write_child() called with undef child");
+ }
+
+ if ($run_away) {
+ $logger->error("server: unable to write message to child: $xml");
+ return; # avoid crash
+ }
+
# tell the child how much data to expect, minus the header
my $write_size;
{use bytes; $write_size = length($xml)}
$self->{sig_pipe} = 0;
local $SIG{'PIPE'} = sub { $self->{sig_pipe} = 1; };
+
+ # XXX: LP#1697029
+ # Double check pipe_to_child, which could have been closed
+ # and deleted via SIGCHLD handler.
+ if ($child->{dead}) {
+ $logger->error("server: child $child is dead in write_child(). ".
+ "unable to send message: $xml");
+ return; # avoid syswrite crash
+
+ } elsif (!$child->{pipe_to_child}) {
+ $logger->error("server: pipe_to_child is undef for child $child. ".
+ "unable to send message: $xml");
+ return; # avoid syswrite crash
+ }
# send message to child data pipe
syswrite($child->{pipe_to_child}, $write_size . $xml);
$self->{num_children}--;
delete $self->{pid_map}->{$pid};
delete $child->{$_} for keys %$child; # destroy with a vengeance
+ $child->{dead} = 1; # in case other references to $child exist
}
$self->spawn_children unless $shutdown;
$self->{parent} = $parent; # Controller parent process
$self->{num_requests} = 0; # total serviced requests
$self->{sig_pipe} = 0; # true if last syswrite failed
+ $self->{dead} = 0; # true if child has been cleaned via SIGCHLD
return $self;
}