This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: CygPerl hangs opening FIFO after fork (in both parent&child)


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/

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]