summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin/fork.cc
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/fork.cc')
-rw-r--r--winsup/cygwin/fork.cc15
1 files changed, 15 insertions, 0 deletions
diff --git a/winsup/cygwin/fork.cc b/winsup/cygwin/fork.cc
index c304d34b0..87315a4c2 100644
--- a/winsup/cygwin/fork.cc
+++ b/winsup/cygwin/fork.cc
@@ -341,6 +341,13 @@ fork_parent (void *stack_here, HANDLE& hParent, dll *&first_dll, bool& load_dlls
else
c_flags |= DETACHED_PROCESS;
+ /* Some file types (currently only sockets) need extra effort in the
+ parent after CreateProcess and before copying the datastructures
+ to the child. So we have to start the child in suspend state,
+ unfortunately, to avoid a race condition. */
+ if (fdtab.need_fixup_before ())
+ c_flags |= CREATE_SUSPENDED;
+
hParent = NULL;
if (!DuplicateHandle (hMainProc, hMainProc, hMainProc, &hParent, 0, 1,
DUPLICATE_SAME_ACCESS))
@@ -429,6 +436,14 @@ fork_parent (void *stack_here, HANDLE& hParent, dll *&first_dll, bool& load_dlls
return -1;
}
+ /* Fixup the parent datastructure if needed and resume the child's
+ main thread. */
+ if (fdtab.need_fixup_before ())
+ {
+ fdtab.fixup_before_fork (pi.dwProcessId);
+ ResumeThread (pi.hThread);
+ }
+
pinfo forked (cygwin_pid (pi.dwProcessId), 1);
/* Initialize things that are done later in dll_crt0_1 that aren't done