develooper Front page | perl.perl5.porters | Postings from April 2010

Re: [PATCH] Attempt at improving the perlipc docs

Thread Previous | Thread Next
From:
Maik Hentsche
Date:
April 28, 2010 12:16
Subject:
Re: [PATCH] Attempt at improving the perlipc docs
Message ID:
20100428211608.49006b3d@hermes
Sorry for the late reply. My family life took away to much of my
hacking time recently.

Eric Brine <ikegami@adaelis.com> wrote:

> Fixes (1) and (2):

Yes, I didn't see (1) and did not consider (2) to be an issue because
in every case I used it it was not. Certainly, that doesn't mean
anything ;-)

Thinking about your solution I wonder whether it's a good idea to
introduce use subs and open3 in a documentation on wait() and SIGCHLD
handling. Especially, since the documentation mainly addresses newbies
like me and it took me half an hour to _really_ get the feeling of
understanding it. This means an additional explanation of the code
example would be needed even though an example should be as self
explaining as possible. Thus, I still favour the idea of using
non blocking waitpid.

This still leaves us with two possible race conditions. The issue there
is the fact that calling waitpid(-1, WNOHANG) could occasionally return
the pid of system's child.
1.) We could ignore that fact and try to cleanup for a child that is
    not cleanable.
2.) Safe the pid returned by fork, only cleanup when waitpid returns a
    saved pid and live with the fact that the child could die before we
    got the chance to save it's pid for the signal handler (thus not
    cleaning up even though we should). This cleanup might include
    closing IPC handles. I'm not sure whether your approach handles
    this correctly. I think it does not.

The example below follows the second approach.

use POSIX ":sys_wait_h"; # for nonblocking read

my %children;

$SIG{CHLD} = sub {
# don't change $! and $? outside handler
        local ($!,$?);
        my $pid = waitpid(-1, WNOHANG);
        return if $pid == -1;
	return unless defined $children{$pid};	
	delete $children{$pid};
        cleanup_child($pid, $?);
};

while(1){
        my $pid = fork();
        if ($pid == 0){
            ...
            exit 0;
        } else {
	    $children{$pid}=1;
            ...
            system($command);
            ...
       }
}

Thanks for your comments, so long
Maik

Thread Previous | Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About