[newlib-cygwin] Cygwin: FIFO: stop the listen_client thread before fork/exec

Ken Brown kbrown@sourceware.org
Tue Apr 23 12:17:00 GMT 2019


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=4443100b53f4ede899da9ebcdea87d3dea93eb4a

commit 4443100b53f4ede899da9ebcdea87d3dea93eb4a
Author: Ken Brown <kbrown@cornell.edu>
Date:   Sat Apr 20 11:41:12 2019 -0400

    Cygwin: FIFO: stop the listen_client thread before fork/exec
    
    Add methods need_fixup_before, init_fixup_before, and
    fixup_before_fork_exec to accomplish this.  Stopping the thread makes
    sure that the client handler lists of the parent and child remain in
    sync while the forking/execing is in progress.

Diff:
---
 winsup/cygwin/fhandler.h       |  3 +++
 winsup/cygwin/fhandler_fifo.cc | 15 +++++++++++++--
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index da007ee..0df25aa 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -1300,6 +1300,9 @@ public:
   void __reg3 raw_read (void *ptr, size_t& ulen);
   ssize_t __reg3 raw_write (const void *ptr, size_t ulen);
   bool arm (HANDLE h);
+  bool need_fixup_before () const { return reader; }
+  int fixup_before_fork_exec (DWORD) { return stop_listen_client (); }
+  void init_fixup_before ();
   void fixup_after_fork (HANDLE);
   void fixup_after_exec ();
   int __reg2 fstatvfs (struct statvfs *buf);
diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc
index 3ee307b..9b94a6d 100644
--- a/winsup/cygwin/fhandler_fifo.cc
+++ b/winsup/cygwin/fhandler_fifo.cc
@@ -522,7 +522,10 @@ fhandler_fifo::open (int flags, mode_t)
 	  goto out;
 	}
       else
-	res = success;
+	{
+	  init_fixup_before ();
+	  res = success;
+	}
     }
 
   /* If we're writing, wait for read_ready and then connect to the
@@ -752,7 +755,7 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len)
 {
   size_t orig_len = len;
 
-  /* Start the listen_client thread if necessary (e.g., after dup or fork). */
+  /* Start the listen_client thread if necessary (e.g., after fork or exec). */
   if (!listen_client_thr && !listen_client ())
     goto errout;
 
@@ -934,11 +937,19 @@ fhandler_fifo::dup (fhandler_base *child, int flags)
   fhf->fifo_client_unlock ();
   if (!reader || fhf->listen_client ())
     ret = 0;
+  if (reader)
+    fhf->init_fixup_before ();
 out:
   return ret;
 }
 
 void
+fhandler_fifo::init_fixup_before ()
+{
+  cygheap->fdtab.inc_need_fixup_before ();
+}
+
+void
 fhandler_fifo::fixup_after_fork (HANDLE parent)
 {
   fhandler_base::fixup_after_fork (parent);



More information about the Cygwin-cvs mailing list