[PATCH]: broken pipe
Mon Aug 30 04:22:00 GMT 2004
On Sun, Aug 29, 2004 at 12:51:54PM -0400, Pierre A. Humblet wrote:
>I have been investigation the broken pipe problem reported in
>Thanks to Errol for providing a simple test case, from which
>I wrote a C program with similar features.
>Once in many thousands fork will return 0 to the parent.
>The parent then thinks it is the child, closes the reader
>side of the pipe and starts writing to the pipe, causing its death.
>Meanwhile the child also writes to the pipe and dies of the same cause.
>There is a scenario that explains the above observations.
>Both the parent and the child try to create the child pinfo
>simultaneously. The following sequence can occur:
> - child creates pinfo
> - parent opens pinfo
> - parent reads cygpid from pinfo (== 0)
> - child writes its cygpid
>The parent fork then returns 0.
>My solution is for the parent fork to return the cygpid calculated
>from the winpid.
>The test program is still running after 100,000 fork/exec/pipe,
>a longevity record.
Wouldn't the below solve this problem more minimally? It moves the
setting of forked_pid to after it is known that the pinfo structure
has been filled out.
>Two other comments:
>- there is still a race to create the pinfo. Hopefully all versions
>of Windows handle it properly. To be on the safe side, the parent could
>open (not create) the pinfo after the child's longjmp.
>- the parent copies myself->progname into the child. This seems
>duplicative, given that the child always sets progname from
>GetModuleFileName in set_myself.
I'm not clear on why you think the race is a problem. The end result
should be that the correct info is in the pinfo regardless. It shouldn't
matter if CreateFileMapping or OpenFileMapping is called.
RCS file: /cvs/src/src/winsup/cygwin/fork.cc,v
retrieving revision 1.131
diff -u -p -r1.131 fork.cc
--- fork.cc 7 Mar 2004 04:57:47 -0000 1.131
+++ fork.cc 30 Aug 2004 04:17:17 -0000
@@ -514,8 +514,6 @@ fork_parent (HANDLE& hParent, dll *&firs
- forked_pid = forked->pid;
/* Initialize things that are done later in dll_crt0_1 that aren't done
for the forkee. */
strcpy (forked->progname, myself->progname);
@@ -552,6 +550,7 @@ fork_parent (HANDLE& hParent, dll *&firs
if (!sync_with_child (pi, subproc_ready, true, "waiting for longjmp"))
+ forked_pid = forked->pid;
/* CHILD IS STOPPED */
debug_printf ("child is alive (but stopped)");
More information about the Cygwin-patches