[newlib-cygwin] Cygwin: FIFO: re-implement duplexers

Ken Brown kbrown@sourceware.org
Thu May 9 18:52:00 GMT 2019


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

commit 00b2e56d3184231264005d6b1f60b1f40023907b
Author: Ken Brown <kbrown@cornell.edu>
Date:   Thu May 9 11:23:44 2019 -0400

    Cygwin: FIFO: re-implement duplexers
    
    When opening a duplexer, open a client connection to the first client
    handler.  Previously we gave the duplexer a bogus write handle, which
    was just a duplicate of the first client handler's handle.  This meant
    that we had a pipe server with no clients connected, and all I/O
    attempts failed with STATUS_PIPE_LISTENING.
    
    Extend the last fcntl change to duplexers.
    
    Remove a now unused fifo_client_handler constructor, as well as the
    long unusued method fifo_client_handler::connect.
    
    Don't create the pipe in duplex mode; the server handle will only be
    used for reading.

Diff:
---
 winsup/cygwin/fhandler.h       |  4 ----
 winsup/cygwin/fhandler_fifo.cc | 41 +++++++++++------------------------------
 2 files changed, 11 insertions(+), 34 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 3b2b194..16165c4 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -1251,10 +1251,6 @@ struct fifo_client_handler
   fifo_client_connect_state state;
   HANDLE connect_evt;
   fifo_client_handler () : fh (NULL), state (fc_unknown), connect_evt (NULL) {}
-  fifo_client_handler (fhandler_base *_fh, fifo_client_connect_state _state,
-		       HANDLE _connect_evt)
-    : fh (_fh), state (_state), connect_evt (_connect_evt) {}
-  int connect ();
   int close ();
 };
 
diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc
index 8dfe496..1a16109 100644
--- a/winsup/cygwin/fhandler_fifo.cc
+++ b/winsup/cygwin/fhandler_fifo.cc
@@ -175,8 +175,6 @@ fhandler_fifo::create_pipe_instance (bool first)
     }
   access = GENERIC_READ | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES
     | SYNCHRONIZE;
-  if (first && duplexer)
-    access |= GENERIC_WRITE;
   sharing = FILE_SHARE_READ | FILE_SHARE_WRITE;
   hattr = OBJ_INHERIT;
   if (first)
@@ -474,41 +472,23 @@ fhandler_fifo::open (int flags, mode_t)
   /* If we're a duplexer, create the pipe and the first client handler. */
   if (duplexer)
     {
-      HANDLE ph, connect_evt;
-      fhandler_base *fh;
-
-      ph = create_pipe_instance (true);
-      if (!ph)
-	{
-	  res = error_errno_set;
-	  goto out;
-	}
-      set_handle (ph);
-      set_pipe_non_blocking (ph, true);
-      if (!(fh = build_fh_dev (dev ())))
+      if (add_client_handler () < 0)
 	{
-	  set_errno (EMFILE);
 	  res = error_errno_set;
 	  goto out;
 	}
-      if (!DuplicateHandle (GetCurrentProcess (), ph, GetCurrentProcess (),
-			    &fh->get_handle (), 0, true, DUPLICATE_SAME_ACCESS))
+      NTSTATUS status = open_pipe ();
+      if (NT_SUCCESS (status))
 	{
-	  res = error_set_errno;
-	  fh->close ();
-	  delete fh;
-	  goto out;
+	  record_connection (fc_handler[0]);
+	  set_pipe_non_blocking (get_handle (), flags & O_NONBLOCK);
 	}
-      fh->set_flags (flags);
-      if (!(connect_evt = create_event ()))
+      else
 	{
+	  __seterrno_from_nt_status (status);
 	  res = error_errno_set;
-	  fh->close ();
-	  delete fh;
 	  goto out;
 	}
-      fc_handler[0] = fifo_client_handler (fh, fc_connected, connect_evt);
-      nconnected = nhandlers = 1;
     }
 
   /* If we're reading, start the listen_client thread (which should
@@ -889,12 +869,13 @@ fhandler_fifo::close ()
   return fhandler_base::close () || ret;
 }
 
-/* If we're a writer, keep the nonblocking state of the windows pipe
-   in sync with our nonblocking state. */
+/* If we have a write handle (i.e., we're a duplexer or a writer),
+   keep the nonblocking state of the windows pipe in sync with our
+   nonblocking state. */
 int
 fhandler_fifo::fcntl (int cmd, intptr_t arg)
 {
-  if (cmd != F_SETFL || !writer)
+  if (cmd != F_SETFL || nohandle ())
     return fhandler_base::fcntl (cmd, arg);
 
   const bool was_nonblocking = is_nonblocking ();



More information about the Cygwin-cvs mailing list