[newlib-cygwin] Cygwin: FIFO: simplify raw_read

Ken Brown kbrown@sourceware.org
Sun Jun 23 17:09:00 GMT 2019


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

commit 5b2696cb83617234446f3f4a304573c6aa3125d3
Author: Ken Brown <kbrown@cornell.edu>
Date:   Fri Jun 21 17:33:30 2019 -0400

    Cygwin: FIFO: simplify raw_read
    
    Call NtReadFile directly instead of calling fhandler_base::raw_read.
    In addition to being simpler, this gives us access to the return value
    from NtReadFile.

Diff:
---
 winsup/cygwin/fhandler_fifo.cc | 50 ++++++++++++++++++++++++++----------------
 1 file changed, 31 insertions(+), 19 deletions(-)

diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc
index b96c4d5..b755544 100644
--- a/winsup/cygwin/fhandler_fifo.cc
+++ b/winsup/cygwin/fhandler_fifo.cc
@@ -802,8 +802,6 @@ fhandler_fifo::check_listen_client_thread ()
 void __reg3
 fhandler_fifo::raw_read (void *in_ptr, size_t& len)
 {
-  size_t orig_len = len;
-
   /* Make sure the lct is running. */
   int res = check_listen_client_thread ();
   debug_printf ("lct status %d", res);
@@ -826,26 +824,40 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len)
       for (int i = 0; i < nhandlers; i++)
 	if (fc_handler[i].state == fc_connected)
 	  {
-	    len = orig_len;
-	    fc_handler[i].fh->fhandler_base::raw_read (in_ptr, len);
-	    ssize_t nread = (ssize_t) len;
-	    if (nread > 0)
-	      {
-		fifo_client_unlock ();
-		return;
-	      }
-	    /* If the pipe is empty, we  get nread == -1 with
-	       ERROR_NO_DATA. */
-	    else if (nread < 0 && GetLastError () != ERROR_NO_DATA)
-	      {
-		fifo_client_unlock ();
-		goto errout;
-	      }
-	    else if (nread == 0)
-	      /* Client has disconnected. */
+	    NTSTATUS status;
+	    IO_STATUS_BLOCK io;
+	    size_t nbytes = 0;
+
+	    status = NtReadFile (get_fc_handle (i), NULL, NULL, NULL,
+				 &io, in_ptr, len, NULL, NULL);
+	    switch (status)
 	      {
+	      case STATUS_SUCCESS:
+	      case STATUS_BUFFER_OVERFLOW:
+		/* io.Information is supposedly valid. */
+		nbytes = io.Information;
+		if (nbytes > 0)
+		  {
+		    len = nbytes;
+		    fifo_client_unlock ();
+		    return;
+		  }
+		break;
+	      case STATUS_PIPE_EMPTY:
+		break;
+	      case STATUS_PIPE_BROKEN:
+		/* Client has disconnected.  Mark the client handler
+		   to be deleted when it's safe to do that. */
+		fc_handler[i].state = fc_invalid;
+		nconnected--;
+		break;
+	      default:
+		debug_printf ("NtReadFile status %y", status);
+		__seterrno_from_nt_status (status);
 		fc_handler[i].state = fc_invalid;
 		nconnected--;
+		fifo_client_unlock ();
+		goto errout;
 	      }
 	  }
       fifo_client_unlock ();



More information about the Cygwin-cvs mailing list