CygPerl hangs opening FIFO after fork (in both parentchild)
The attached test case is simple and fairly short. It does not depend on File::BOM (and has none of the code from it). It's only dependency (other than perl) is the POSIX module, where, from, the fifo command is taken. Conceptually, it is simple: - Create fifo (works) - Fork(works) - Open fifo for communication between parent and child (FAILS) (if successful, try to pass a short message, from child to parent, parent validates, then both processes exit) - Both the child and the parent hang on the open. Fork by itself works. Fifo communication, by itself, works. Is this a simple enough test case? Linda #!/usr/bin/perl -w use strict; use POSIX qw( mkfifo ); my $message = EOM; Hello, World. That is all EOM my $testno=1; #unbuffer outputs select STDERR; $|=1; select STDOUT; $|=1; sub check { my ($stat,$msg)[EMAIL PROTECTED]; printf Test $testno had status %s;%s\n, $stat?pass:fail, $msg?(msg=$msg):; ++$testno; return $stat; } my $fifo = 'test_fifo'; unlink $fifo if (-e $fifo); #prior hang?: cleanup check( mkfifo($fifo, 0700), Created fifo $fifo ) or warn $!; my $pid = fork; if ($pid) { check( 1 ,parent: forked ok, about to open fifo); open my $reader, '', $fifo or die $$: Couldn't read '$fifo': $!; cygwin never gets here check( 1, parent: after open about to read from child); my $child_msg = $reader; check ( ($child_msg eq $message) , parent: received msg from child, closing reader...); close $reader; check( 1 ,parent: closed reader, about to wait on child); check( (waitpid($pid,0) 0), waitpid($pid) 0); check(unlink($fifo), removed $fifo) or warn $!; } elsif (defined $pid) { check( 1, child: fork ok, about to open fifo); open my $writer, '', $fifo or die $$: Couldn't write '$fifo': $!; cygwin never gets here check (1, child: after opening fifo for write; about to print); print $writer $message; # diag $$: Wrote , length $message, bytes to fifo; check (1, child: wrote; about to close); close $writer; check (1, child: closed; about to exit); exit 0; } else { die $0: fork failed: $!; } -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
Re: CygPerl hangs opening FIFO after fork (in both parentchild)
Linda Walsh wrote: The attached test case is simple and fairly short. It does not depend on File::BOM (and has none of the code from it). It's only dependency (other than perl) is the POSIX module, where, from, the fifo command is taken. This appears to be a deadlock in the Cygwin DLL when both the reader and writer end of a fifo tries to open the file at the same time (or nearly the same time.) They end up signaling each other to ask about the other end of the pipe, and hang there. It has nothing to do with perl or fork, as far as I can tell -- the attached C testcase will work fine if the reader end sleeps briefly to ensure the opening order. It's just a classic race condition somewhere. Brian#include stdio.h #include string.h #include stdlib.h #include unistd.h #include fcntl.h #include sys/stat.h #include sys/wait.h #define FIFO_FILENAME test_fifo #define ERROR_EXIT(x) { perror(x); exit (EXIT_FAILURE); } int main (int argc, char **argv) { int fd; pid_t pid; unlink (FIFO_FILENAME); if (mkfifo (FIFO_FILENAME, 0700) == -1) ERROR_EXIT (mkfifo); if ((pid = fork ()) 0) { printf (parent: I am %d, child is %d\n, getpid (), pid); if (argc 1) { puts (parent: sleeping); sleep (1); } puts (parent: opening fifo); if ((fd = open (FIFO_FILENAME, O_RDONLY)) == -1) ERROR_EXIT (parent open); puts (parent: closing fifo); close (fd); puts (parent: waiting for child); if (waitpid (pid, NULL, 0) != pid) ERROR_EXIT (parent waitpid); puts (parent: removing fifo); if (unlink (FIFO_FILENAME) != 0) ERROR_EXIT (parent unlink); puts (parent: exiting); exit (EXIT_SUCCESS); } else if (pid == 0) { puts (child: opening fifo); if ((fd = open (FIFO_FILENAME, O_WRONLY)) == -1) ERROR_EXIT (child open); puts (child: closing fifo); close (fd); puts (child: exiting); exit (EXIT_SUCCESS); } else ERROR_EXIT (fork); } -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
Re: CygPerl hangs opening FIFO after fork (in both parentchild)
On Thu, Jun 22, 2006 at 06:53:38PM -0700, Brian Dessent wrote: Linda Walsh wrote: The attached test case is simple and fairly short. It does not depend on File::BOM (and has none of the code from it). It's only dependency (other than perl) is the POSIX module, where, from, the fifo command is taken. This appears to be a deadlock in the Cygwin DLL when both the reader and writer end of a fifo tries to open the file at the same time (or nearly the same time.) They end up signaling each other to ask about the other end of the pipe, and hang there. It has nothing to do with perl or fork, as far as I can tell -- the attached C testcase will work fine if the reader end sleeps briefly to ensure the opening order. It's just a classic race condition somewhere. Yep. It's a deadlock which uncovered a race. It should be fixed in the next floor wax available at: http://cygwin.com/snapshots/ And thanks for the test case which illustrated the problem. cgf -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
Re: CygPerl hangs opening FIFO after fork (in both parentchild)
On Thu, Jun 22, 2006 at 06:53:38PM -0700, Brian Dessent wrote: Linda Walsh wrote: The attached test case is simple and fairly short. It does not depend on File::BOM (and has none of the code from it). It's only dependency (other than perl) is the POSIX module, where, from, the fifo command is taken. This appears to be a deadlock in the Cygwin DLL when both the reader and writer end of a fifo tries to open the file at the same time (or nearly the same time.) They end up signaling each other to ask about the other end of the pipe, and hang there. It has nothing to do with perl or fork, as far as I can tell -- the attached C testcase will work fine if the reader end sleeps briefly to ensure the opening order. It's just a classic race condition somewhere. Good job isolating this problem, Linda and Brian. -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/
Re: CygPerl hangs opening FIFO after fork (in both parentchild)
On Thu, Jun 22, 2006 at 07:52:37PM -0700, Yitzchak Scott-Thoennes wrote: On Thu, Jun 22, 2006 at 06:53:38PM -0700, Brian Dessent wrote: Linda Walsh wrote: The attached test case is simple and fairly short. It does not depend on File::BOM (and has none of the code from it). It's only dependency (other than perl) is the POSIX module, where, from, the fifo command is taken. This appears to be a deadlock in the Cygwin DLL when both the reader and writer end of a fifo tries to open the file at the same time (or nearly the same time.) They end up signaling each other to ask about the other end of the pipe, and hang there. It has nothing to do with perl or fork, as far as I can tell -- the attached C testcase will work fine if the reader end sleeps briefly to ensure the opening order. It's just a classic race condition somewhere. Good job isolating this problem, Linda and Brian. Not to denigrate Brian's analysis but, AFAICT, there was already a snapshot with the fix by the time he sent his mail. I only point this out because I didn't want it to look like I was ungrateful for Brian's analysis or that I used it and didn't give credit. cgf -- Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple Problem reports: http://cygwin.com/problems.html Documentation: http://cygwin.com/docs.html FAQ: http://cygwin.com/faq/