Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

we have a script that cron runs to run user scripts for us, log their results, make sure that only one of them is running, etc. Couple of days ago a user's script was hung for no apparent reason. So I tried to reproduce similar behavior and a buddy and I got it down to a pretty small subset of the functionality. I'm hoping maybe someone can shed a little light on what's going on here.

The stripped down version of the script-running script is this:

#!/usr/bin/perl -w use strict; use Proc::Spawn; my ($pid, $IN, $OUT, $ERROR) = spawn(\@ARGV); #fix by uncommenting this #while( <$ERROR>){}; # either of these hang my $junk = eof($OUT); #while (<$OUT>){};

And the stripped-down version of the user code is this:

#!/usr/bin/perl -w use strict; warn "x" x shift(@ARGV) . "\n";

so, save them puppies in "runner.pl" and "user.pl", chmod +x them, and issue this command:

[msouth@jinx GUI-APP bin]$ ./runner.pl ./user.pl 4095

then issue this command:

[msouth@jinx GUI-APP bin]$ ./runner.pl ./user.pl 4096

(then, if your system works like mine, you will want to do a control-c or something because it's just hanging there).

You can also test the commented assertion that unloading user.pl's stderr of its burden eliminates the problem. (Does on my system.)

(BTW, perl -v says:

This is perl, v5.6.1 built for i686-linux )

Just to make sure that I'm not confusing anyone, Proc::Spawn is producing IO::Handle objects there (lest anyone think that my subject implied I was doing this on vanilla filehandles).

I don't know diddly about IO. Anyone? (I would like to hear even if it's just that you can/can't reproduce it.)

Replies are listed 'Best First'.
Re: eof(FH) hanging when 4096 chars waiting on stderr (or something like that)
by hv (Prior) on Apr 28, 2004 at 10:34 UTC

    I haven't looked at the code for Proc::Spawn, but from the symptoms you describe I would guess they are pipes; as I understand it, it is quite normal for a pipe to have a 4k buffer, and when the buffer is full the writer will block on any attempt to write more data to the pipe until the reader reads some out.

    So in this case you have deadlock: the writer has written 4096 'x's to the stderr pipe, filling it, and is blocked trying to write the newline; the reader is sitting waiting for something on stdout, and there's nothing there (nor has it been closed, so there is no eof).

    To avoid such deadlock you need to use nonblocking reads throughout, and be prepared to read from whichever handle has data ready, which you'd normally do with a 4-arg select loop.

    You may also want to look at File::Tail which wraps up some of those details for you.

    Hugo

Re: eof(FH) hanging when 4096 chars waiting on stderr (or something like that)
by msouth (Sexton) on Apr 28, 2004 at 05:59 UTC
    Sorry, that was me, I didn't mean to post that anonymously.