public inbox for cygwin-developers@cygwin.com
 help / color / mirror / Atom feed
From: Takashi Yano <takashi.yano@nifty.ne.jp>
To: cygwin-developers@cygwin.com
Subject: Re: cygrunsrv + sshd + rsync = 20 times too slow -- throttled?
Date: Tue, 14 Sep 2021 17:08:38 +0900	[thread overview]
Message-ID: <20210914170838.6393026ac3eaa4cd4e3d9618@nifty.ne.jp> (raw)
In-Reply-To: <20210914043718.f420491c6723f3dc2e2d9753@nifty.ne.jp>

[-- Attachment #1: Type: text/plain, Size: 4129 bytes --]

On Tue, 14 Sep 2021 04:37:18 +0900
Takashi Yano wrote:
> On Mon, 13 Sep 2021 20:32:33 +0200
> Corinna Vinschen wrote:
> > On Sep 12 20:04, Takashi Yano wrote:
> > > On Sun, 12 Sep 2021 17:48:49 +0900
> > > Takashi Yano wrote:
> > > > Hmm. Then, what about PoC code attached? This returns to Corinna's
> > > > query_hdl, and counts read/write handles to detect closing reader side.
> > > > 
> > > > If the number of read handles is equal to number of write handles,
> > > > only the pairs of write handle and query_hdl are alive. So, read pipe
> > > > supposed to be closed.
> > > > 
> > > > This patch depends another patch I posted a few hours ago.
> > > 
> > > Revised a bit.
> > > [...]
> > 
> > What I miss is a bit more detailed commit message...
> 
> I am sorry, I will add more detail commit message.

Done.

> > > diff --git a/winsup/cygwin/fhandler_pipe.cc b/winsup/cygwin/fhandler_pipe.cc
> > > index 9b4255cfd..b051f5c03 100644
> > > --- a/winsup/cygwin/fhandler_pipe.cc
> > > +++ b/winsup/cygwin/fhandler_pipe.cc
> > > @@ -56,6 +56,8 @@ fhandler_pipe::set_pipe_non_blocking (bool nonblocking)
> > >    fpi.ReadMode = FILE_PIPE_BYTE_STREAM_MODE;
> > >    fpi.CompletionMode = nonblocking ? FILE_PIPE_COMPLETE_OPERATION
> > >      : FILE_PIPE_QUEUE_OPERATION;
> > > +  if (query_hdl)
> > > +    fpi.CompletionMode = FILE_PIPE_COMPLETE_OPERATION;
> > 
> > This should be a single expression, i.e.
> > 
> >    fpi.CompletionMode = nonblocking || query_hdl
> >                         ? FILE_PIPE_COMPLETE_OPERATION
> >                         : FILE_PIPE_QUEUE_OPERATION;
> > 
> > ideally combined with a comment.
> 
> Thanks. I'll do that.

Done.


> > But then again... you're basically switching the write side of
> > a pipe to nonblocking mode unconditionally.  The downside is a
> > busy wait:
> > 
> > >  fhandler_pipe_fifo::raw_write (const void *ptr, size_t len)
> > >  {
> > > @@ -493,7 +490,20 @@ fhandler_pipe_fifo::raw_write (const void *ptr, size_t len)
> > >  			      get_obj_handle_count (select_sem), NULL);
> > >  	  /* 0 bytes returned?  EAGAIN.  See above. */
> > >  	  if (NT_SUCCESS (status) && nbytes == 0)
> > > -	    set_errno (EAGAIN);
> > > +	    {
> > > +	      if (reader_closed ())
> > > +		{
> > > +		  set_errno (EPIPE);
> > > +		  raise (SIGPIPE);
> > > +		}
> > > +	      else if (is_nonblocking ())
> > > +		set_errno (EAGAIN);
> > > +	      else
> > > +		{
> > > +		  cygwait (select_sem, 10);
> > > +		  continue;
> > 
> > I'm a bit puzzled.  The cygwait branch neglects to check if select_sem
> > is NULL (the preceeding ReleaseSemaphore expression does!)
> > And then it doesn't matter if the caller got blocked or not, it will
> > always perform a continue.  So why do it at all?  Worse, if this
> > expression loops, it will eat up the semaphore, because each call will
> > decrement the semaphore count until it blocks.  That sounds wrong to me.
> 
> It is by design. ReleaseSemaphore() releases maximum number of semaphore
> which the waiter can exists. If only one writer and one reader exist,
> ReleaseSemaphore releases 2 semaphores. Then cygwait here consume semaphore
> two times and return to wait state.
> This wait state is released by raw_read() or close().
>  
> > Btw., while looking into the current pipe code, I wonder what select_sem
> > is doing in the pipe code at all so far.  It gets released, but it never
> > gets waited on?!?  Am I missing something?
> 
> The semaphore is waited in select.cc.
> But, wait. Wat happens if select() is not called? Released semaphore
> can be accumulated up to INT32_MAX!!?
> 
> Let me consider.

See the second patch attached. With this patch, only minimum number
of semaphores needed are released.


Please apply following two patches I attached to previous mail first:
0001-Cygwin-fhandler_base-dup-Reflect-O_CLOEXEC-to-inheri.patch
0002-Cygwin-pipe-fifo-Call-set_no_inheritance-for-adjunct.patch

Then, apply the patches attached this mail.
0001-Cygwin-pipe-Use-read-pipe-handle-for-select-on-write.patch
0002-Cygwin-pipe-fifo-Release-select_sem-semaphore-as-muc.patch

Thanks

-- 
Takashi Yano <takashi.yano@nifty.ne.jp>

[-- Attachment #2: 0001-Cygwin-pipe-Use-read-pipe-handle-for-select-on-write.patch --]
[-- Type: application/octet-stream, Size: 12170 bytes --]

From 611ac5f87df0b5156e3ec82e98af27892a9c8882 Mon Sep 17 00:00:00 2001
From: Takashi Yano <takashi.yano@nifty.ne.jp>
Date: Tue, 14 Sep 2021 12:27:33 +0900
Subject: [PATCH 1/2] Cygwin: pipe: Use read pipe handle for select() on write
 pipe.

- Usually WriteQuotaAvailable retrieved by NtQueryInformationFile()
  on the write side reflects the space available in the inbound buffer
  on the read side. However, if a pipe read is currently pending,
  WriteQuotaAvailable on the write side is decremented by the number
  of bytes the read side is requesting. So it's possible (even likely)
  that WriteQuotaAvailable is 0, even if the inbound buffer on the
  read side is not full. This can lead to a deadlock situation:
  The reader is waiting for data, but select on the writer side
  assumes that no space is available in the read side inbound buffer.

  Currently, to avoid this stuation, read() does not request larger
  block than pipe size - 1. However, this mechanism does not take
  effect if the reader side is non-cygwin app.

  The only reliable information is available on the read side, so
  fetch info from the read side via the pipe-specific query handle
  (query_hdl) introduced.
---
 winsup/cygwin/fhandler.h       |  14 ++++-
 winsup/cygwin/fhandler_pipe.cc | 105 +++++++++++++++++++++++----------
 winsup/cygwin/select.cc        |  52 +++++++++++++---
 winsup/cygwin/spawn.cc         |  11 ++++
 4 files changed, 144 insertions(+), 38 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index 46381c397..db2325144 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -1176,10 +1176,22 @@ class fhandler_pipe_fifo: public fhandler_base
 {
  protected:
   size_t pipe_buf_size;
+  HANDLE query_hdl;
 
  public:
   fhandler_pipe_fifo ();
 
+  HANDLE get_query_handle () const { return query_hdl; }
+  void close_query_handle ()
+  {
+    if (query_hdl)
+      {
+	CloseHandle (query_hdl);
+	query_hdl = NULL;
+      }
+  }
+  bool reader_closed ();
+
   ssize_t __reg3 raw_write (const void *ptr, size_t len);
 
 };
@@ -1189,7 +1201,6 @@ class fhandler_pipe: public fhandler_pipe_fifo
 private:
   HANDLE read_mtx;
   pid_t popen_pid;
-  void set_pipe_non_blocking (bool nonblocking);
 public:
   fhandler_pipe ();
 
@@ -1237,6 +1248,7 @@ public:
     fh->copy_from (this);
     return fh;
   }
+  void set_pipe_non_blocking (bool nonblocking);
 };
 
 #define CYGWIN_FIFO_PIPE_NAME_LEN     47
diff --git a/winsup/cygwin/fhandler_pipe.cc b/winsup/cygwin/fhandler_pipe.cc
index da473a1dc..4dab3015d 100644
--- a/winsup/cygwin/fhandler_pipe.cc
+++ b/winsup/cygwin/fhandler_pipe.cc
@@ -54,8 +54,12 @@ fhandler_pipe::set_pipe_non_blocking (bool nonblocking)
   FILE_PIPE_INFORMATION fpi;
 
   fpi.ReadMode = FILE_PIPE_BYTE_STREAM_MODE;
-  fpi.CompletionMode = nonblocking ? FILE_PIPE_COMPLETE_OPERATION
-    : FILE_PIPE_QUEUE_OPERATION;
+  /* If query_hdl is set, write pipe should check reader_closed()
+     while raw_read(). If the pipe is blocking, raw_write() stops
+     at NtWriteFile() and loses the chance to check it. Therefore,
+     always set write pipe to non-blocking. */
+  fpi.CompletionMode = (nonblocking || query_hdl)
+    ? FILE_PIPE_COMPLETE_OPERATION : FILE_PIPE_QUEUE_OPERATION;
   status = NtSetInformationFile (get_handle (), &io, &fpi, sizeof fpi,
 				 FilePipeInformation);
   if (!NT_SUCCESS (status))
@@ -202,6 +206,8 @@ fhandler_pipe::open_setup (int flags)
       if (!read_mtx)
 	debug_printf ("CreateMutex failed: %E");
     }
+  if (get_dev () == FH_PIPEW && !query_hdl)
+    set_pipe_non_blocking (is_nonblocking ());
 }
 
 off_t
@@ -268,39 +274,22 @@ fhandler_pipe::raw_read (void *ptr, size_t& len)
   while (nbytes < len)
     {
       ULONG_PTR nbytes_now = 0;
-      size_t left = len - nbytes;
-      ULONG len1 = (ULONG) left;
+      ULONG len1 = (ULONG) (len - nbytes);
       waitret = WAIT_OBJECT_0;
 
       if (evt)
 	ResetEvent (evt);
-      if (!is_nonblocking ())
+      FILE_PIPE_LOCAL_INFORMATION fpli;
+      status = NtQueryInformationFile (get_handle (), &io,
+				       &fpli, sizeof (fpli),
+				       FilePipeLocalInformation);
+      if (NT_SUCCESS (status))
 	{
-	  FILE_PIPE_LOCAL_INFORMATION fpli;
-
-	  /* If the pipe is empty, don't request more bytes than pipe
-	     buffer size - 1. Pending read lowers WriteQuotaAvailable on
-	     the write side and thus affects select's ability to return
-	     more or less reliable info whether a write succeeds or not. */
-	  ULONG chunk = pipe_buf_size - 1;
-	  status = NtQueryInformationFile (get_handle (), &io,
-					   &fpli, sizeof (fpli),
-					   FilePipeLocalInformation);
-	  if (NT_SUCCESS (status))
-	    {
-	      if (fpli.ReadDataAvailable > 0)
-		chunk = left;
-	      else if (nbytes != 0)
-		break;
-	      else
-		chunk = fpli.InboundQuota - 1;
-	    }
-	  else if (nbytes != 0)
-	    break;
-
-	  if (len1 > chunk)
-	    len1 = chunk;
+	if (fpli.ReadDataAvailable == 0 && nbytes != 0)
+	  break;
 	}
+      else if (nbytes != 0)
+	break;
       status = NtReadFile (get_handle (), evt, NULL, NULL, &io, ptr,
 			   len1, NULL, NULL);
       if (evt && status == STATUS_PENDING)
@@ -385,6 +374,16 @@ fhandler_pipe::raw_read (void *ptr, size_t& len)
   len = nbytes;
 }
 
+bool
+fhandler_pipe_fifo::reader_closed ()
+{
+  if (!query_hdl)
+    return false;
+  int n_reader = get_obj_handle_count (query_hdl);
+  int n_writer = get_obj_handle_count (get_handle ());
+  return n_reader == n_writer;
+}
+
 ssize_t __reg3
 fhandler_pipe_fifo::raw_write (const void *ptr, size_t len)
 {
@@ -493,7 +492,20 @@ fhandler_pipe_fifo::raw_write (const void *ptr, size_t len)
 			      get_obj_handle_count (select_sem), NULL);
 	  /* 0 bytes returned?  EAGAIN.  See above. */
 	  if (NT_SUCCESS (status) && nbytes == 0)
-	    set_errno (EAGAIN);
+	    {
+	      if (reader_closed ())
+		{
+		  set_errno (EPIPE);
+		  raise (SIGPIPE);
+		}
+	      else if (is_nonblocking ())
+		set_errno (EAGAIN);
+	      else
+		{
+		  cygwait (select_sem, 10);
+		  continue;
+		}
+	    }
 	}
       else if (STATUS_PIPE_IS_CLOSED (status))
 	{
@@ -523,6 +535,8 @@ fhandler_pipe::set_close_on_exec (bool val)
     set_no_inheritance (read_mtx, val);
   if (select_sem)
     set_no_inheritance (select_sem, val);
+  if (query_hdl)
+    set_no_inheritance (query_hdl, val);
 }
 
 void
@@ -532,6 +546,9 @@ fhandler_pipe::fixup_after_fork (HANDLE parent)
     fork_fixup (parent, read_mtx, "read_mtx");
   if (select_sem)
     fork_fixup (parent, select_sem, "select_sem");
+  if (query_hdl)
+    fork_fixup (parent, query_hdl, "query_hdl");
+
   fhandler_base::fixup_after_fork (parent);
 }
 
@@ -562,6 +579,15 @@ fhandler_pipe::dup (fhandler_base *child, int flags)
       ftp->close ();
       res = -1;
     }
+  else if (query_hdl &&
+	   !DuplicateHandle (GetCurrentProcess (), query_hdl,
+			    GetCurrentProcess (), &ftp->query_hdl,
+			    0, !(flags & O_CLOEXEC), DUPLICATE_SAME_ACCESS))
+    {
+      __seterrno ();
+      ftp->close ();
+      res = -1;
+    }
 
   debug_printf ("res %d", res);
   return res;
@@ -577,6 +603,8 @@ fhandler_pipe::close ()
       ReleaseSemaphore (select_sem, get_obj_handle_count (select_sem), NULL);
       CloseHandle (select_sem);
     }
+  if (query_hdl)
+    CloseHandle (query_hdl);
   return fhandler_base::close ();
 }
 
@@ -797,6 +825,23 @@ fhandler_pipe::create (fhandler_pipe *fhs[2], unsigned psize, int mode)
 	DuplicateHandle (GetCurrentProcess (), fhs[0]->select_sem,
 			 GetCurrentProcess (), &fhs[1]->select_sem,
 			 0, sa->bInheritHandle, DUPLICATE_SAME_ACCESS);
+      if (!DuplicateHandle (GetCurrentProcess (), r,
+			    GetCurrentProcess (), &fhs[1]->query_hdl,
+			    FILE_READ_DATA, sa->bInheritHandle, 0))
+	{
+	  CloseHandle (fhs[0]->select_sem);
+	  delete fhs[0];
+	  CloseHandle (r);
+	  CloseHandle (fhs[1]->select_sem);
+	  delete fhs[1];
+	  CloseHandle (w);
+	}
+      else
+	{
+	  /* Call set_pipe_non_blocking() again after creating query_hdl. */
+	  fhs[1]->set_pipe_non_blocking (fhs[1]->is_nonblocking ());
+	  res = 0;
+	}
     }
 
   debug_printf ("%R = pipe([%p, %p], %d, %y)", res, fhs[0], fhs[1], psize, mode);
diff --git a/winsup/cygwin/select.cc b/winsup/cygwin/select.cc
index 5e583434c..ac2f3a9e0 100644
--- a/winsup/cygwin/select.cc
+++ b/winsup/cygwin/select.cc
@@ -608,16 +608,47 @@ pipe_data_available (int fd, fhandler_base *fh, HANDLE h, bool writing)
     }
   if (writing)
     {
-      /* WriteQuotaAvailable is decremented by the number of bytes requested
-	 by a blocking reader on the other side of the pipe.  Cygwin readers
-	 are serialized and never request a number of bytes equivalent to the
-	 full buffer size.  So WriteQuotaAvailable is 0 only if either the
-	 read buffer on the other side is really full, or if we have non-Cygwin
-	 readers. */
+      /* If there is anything available in the pipe buffer then signal
+        that.  This means that a pipe could still block since you could
+        be trying to write more to the pipe than is available in the
+        buffer but that is the hazard of select().
+
+        Note that WriteQuotaAvailable is unreliable.
+
+        Usually WriteQuotaAvailable on the write side reflects the space
+        available in the inbound buffer on the read side.  However, if a
+        pipe read is currently pending, WriteQuotaAvailable on the write side
+        is decremented by the number of bytes the read side is requesting.
+        So it's possible (even likely) that WriteQuotaAvailable is 0, even
+        if the inbound buffer on the read side is not full.  This can lead to
+        a deadlock situation: The reader is waiting for data, but select
+        on the writer side assumes that no space is available in the read
+        side inbound buffer.
+
+        Consequentially, the only reliable information is available on the
+        read side, so fetch info from the read side via the pipe-specific
+        query handle.  Use fpli.WriteQuotaAvailable as storage for the actual
+        interesting value, which is the InboundQuote on the write side,
+        decremented by the number of bytes of data in that buffer. */
+      /* Note: Do not use NtQueryInformationFile() for query_hdl because
+	 NtQueryInformationFile() seems to interfere with reading pipes
+	 in non-cygwin apps. Instead, use PeekNamedPipe() here. */
+      if (fh->get_device () == FH_PIPEW)
+	{
+	  HANDLE query_hdl = ((fhandler_pipe *) fh)->get_query_handle ();
+	  if (query_hdl)
+	    {
+	      DWORD nbytes_in_pipe;
+	      PeekNamedPipe (query_hdl, NULL, 0, NULL, &nbytes_in_pipe, NULL);
+	      fpli.WriteQuotaAvailable = fpli.InboundQuota - nbytes_in_pipe;
+	    }
+	  else
+	    return 1;
+	}
       if (fpli.WriteQuotaAvailable > 0)
 	{
 	  paranoid_printf ("fd %d, %s, write: size %u, avail %u", fd,
-			   fh->get_name (), fpli.OutboundQuota,
+			   fh->get_name (), fpli.InboundQuota,
 			   fpli.WriteQuotaAvailable);
 	  return 1;
 	}
@@ -712,6 +743,13 @@ out:
   h = fh->get_output_handle ();
   if (s->write_selected && dev != FH_PIPER)
     {
+      if (dev == FH_PIPEW && ((fhandler_pipe *) fh)->reader_closed ())
+	{
+	  gotone += s->write_ready = true;
+	  if (s->except_selected)
+	    gotone += s->except_ready = true;
+	  return gotone;
+	}
       gotone += s->write_ready =  pipe_data_available (s->fd, fh, h, true);
       select_printf ("write: %s, gotone %d", fh->get_name (), gotone);
     }
diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc
index 0bde0b04d..6b2026776 100644
--- a/winsup/cygwin/spawn.cc
+++ b/winsup/cygwin/spawn.cc
@@ -657,6 +657,17 @@ child_info_spawn::worker (const char *prog_arg, const char *const *argv,
 		ptys->create_invisible_console ();
 		ptys->setup_locale ();
 	      }
+	    else if (cfd->get_dev () == FH_PIPEW)
+	      {
+		fhandler_pipe *pipe = (fhandler_pipe *)(fhandler_base *) cfd;
+		pipe->close_query_handle ();
+		pipe->set_pipe_non_blocking (false);
+	      }
+	    else if (cfd->get_dev () == FH_PIPER)
+	      {
+		fhandler_pipe *pipe = (fhandler_pipe *)(fhandler_base *) cfd;
+		pipe->set_pipe_non_blocking (false);
+	      }
 	}
 
       bool enable_pcon = false;
-- 
2.33.0


[-- Attachment #3: 0002-Cygwin-pipe-fifo-Release-select_sem-semaphore-as-muc.patch --]
[-- Type: application/octet-stream, Size: 5277 bytes --]

From e5c64960fddd43f08dae7afbe3ae1c75bd41c81d Mon Sep 17 00:00:00 2001
From: Takashi Yano <takashi.yano@nifty.ne.jp>
Date: Tue, 14 Sep 2021 13:10:54 +0900
Subject: [PATCH 2/2] Cygwin: pipe, fifo: Release select_sem semaphore as much
 as needed.

- Currently, raw_read(), raw_write() and close() release select_sem
  unconditionally even if no waiter for select_sem exists. With this
  patch, only the minimum number of semaphores required is released.
---
 winsup/cygwin/fhandler.h       |  4 ++++
 winsup/cygwin/fhandler_fifo.cc | 28 ++++++++++++++++++++++------
 winsup/cygwin/fhandler_pipe.cc | 28 +++++++++++++++++++++-------
 3 files changed, 47 insertions(+), 13 deletions(-)

diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h
index db2325144..9580a698c 100644
--- a/winsup/cygwin/fhandler.h
+++ b/winsup/cygwin/fhandler.h
@@ -1177,6 +1177,7 @@ class fhandler_pipe_fifo: public fhandler_base
  protected:
   size_t pipe_buf_size;
   HANDLE query_hdl;
+  virtual void release_select_sem (const char *) {};
 
  public:
   fhandler_pipe_fifo ();
@@ -1201,6 +1202,7 @@ class fhandler_pipe: public fhandler_pipe_fifo
 private:
   HANDLE read_mtx;
   pid_t popen_pid;
+  void release_select_sem (const char *);
 public:
   fhandler_pipe ();
 
@@ -1444,6 +1446,8 @@ class fhandler_fifo: public fhandler_pipe_fifo
   void shared_fc_handler_updated (bool val)
   { shmem->shared_fc_handler_updated (val); }
 
+  void release_select_sem (const char *);
+
 public:
   fhandler_fifo ();
   ~fhandler_fifo ()
diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc
index 37498f547..489ba528c 100644
--- a/winsup/cygwin/fhandler_fifo.cc
+++ b/winsup/cygwin/fhandler_fifo.cc
@@ -1185,6 +1185,22 @@ fhandler_fifo::take_ownership (DWORD timeout)
   return ret;
 }
 
+void
+fhandler_fifo::release_select_sem (const char *from)
+{
+  LONG n_release;
+  if (reader) /* Number of select() call. */
+    n_release = get_obj_handle_count (select_sem)
+      - get_obj_handle_count (read_ready);
+  else /* Number of select() and reader */
+    n_release = get_obj_handle_count (select_sem)
+      - get_obj_handle_count (get_handle ());
+  debug_printf("%s(%s) release %d", from,
+	       reader ? "reader" : "writer", n_release);
+  if (n_release)
+    ReleaseSemaphore (select_sem, n_release, NULL);
+}
+
 void __reg3
 fhandler_fifo::raw_read (void *in_ptr, size_t& len)
 {
@@ -1372,7 +1388,7 @@ out:
   fifo_client_unlock ();
   reading_unlock ();
   if (select_sem)
-    ReleaseSemaphore (select_sem, get_obj_handle_count (select_sem), NULL);
+    release_select_sem ("raw_read");
 }
 
 int __reg2
@@ -1483,6 +1499,11 @@ fhandler_fifo::cancel_reader_thread ()
 int
 fhandler_fifo::close ()
 {
+  if (select_sem)
+    {
+      release_select_sem ("close");
+      NtClose (select_sem);
+    }
   if (writer)
     {
       nwriters_lock ();
@@ -1574,11 +1595,6 @@ fhandler_fifo::close ()
     NtClose (write_ready);
   if (writer_opening)
     NtClose (writer_opening);
-  if (select_sem)
-    {
-      ReleaseSemaphore (select_sem, get_obj_handle_count (select_sem), NULL);
-      NtClose (select_sem);
-    }
   if (nohandle ())
     return 0;
   else
diff --git a/winsup/cygwin/fhandler_pipe.cc b/winsup/cygwin/fhandler_pipe.cc
index 4dab3015d..c0379e81d 100644
--- a/winsup/cygwin/fhandler_pipe.cc
+++ b/winsup/cygwin/fhandler_pipe.cc
@@ -237,6 +237,22 @@ fhandler_pipe::get_proc_fd_name (char *buf)
   return buf;
 }
 
+void
+fhandler_pipe::release_select_sem (const char *from)
+{
+  LONG n_release;
+  if (get_dev () == FH_PIPER) /* Number of select() and writer */
+    n_release = get_obj_handle_count (select_sem)
+      - get_obj_handle_count (read_mtx);
+  else /* Number of select() call */
+    n_release = get_obj_handle_count (select_sem)
+      - get_obj_handle_count (query_hdl);
+  debug_printf("%s(%s) release %d", from,
+	       get_dev () == FH_PIPER ? "PIPER" : "PIPEW", n_release);
+  if (n_release)
+    ReleaseSemaphore (select_sem, n_release, NULL);
+}
+
 void __reg3
 fhandler_pipe::raw_read (void *ptr, size_t& len)
 {
@@ -328,8 +344,7 @@ fhandler_pipe::raw_read (void *ptr, size_t& len)
 	  ptr = ((char *) ptr) + nbytes_now;
 	  nbytes += nbytes_now;
 	  if (select_sem && nbytes_now > 0)
-	    ReleaseSemaphore (select_sem,
-			      get_obj_handle_count (select_sem), NULL);
+	    release_select_sem ("raw_read");
 	}
       else
 	{
@@ -488,8 +503,7 @@ fhandler_pipe_fifo::raw_write (const void *ptr, size_t len)
 	  ptr = ((char *) ptr) + nbytes_now;
 	  nbytes += nbytes_now;
 	  if (select_sem && nbytes_now > 0)
-	    ReleaseSemaphore (select_sem,
-			      get_obj_handle_count (select_sem), NULL);
+	    release_select_sem ("raw_write");
 	  /* 0 bytes returned?  EAGAIN.  See above. */
 	  if (NT_SUCCESS (status) && nbytes == 0)
 	    {
@@ -596,13 +610,13 @@ fhandler_pipe::dup (fhandler_base *child, int flags)
 int
 fhandler_pipe::close ()
 {
-  if (read_mtx)
-    CloseHandle (read_mtx);
   if (select_sem)
     {
-      ReleaseSemaphore (select_sem, get_obj_handle_count (select_sem), NULL);
+      release_select_sem ("close");
       CloseHandle (select_sem);
     }
+  if (read_mtx)
+    CloseHandle (read_mtx);
   if (query_hdl)
     CloseHandle (query_hdl);
   return fhandler_base::close ();
-- 
2.33.0


  parent reply	other threads:[~2021-09-14  8:08 UTC|newest]

Thread overview: 250+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <41A583E1-C8E7-42AB-9F24-EEC33A41EC60@house.org>
     [not found] ` <20210825201845.07b6400b79dc5558a7761efe@nifty.ne.jp>
     [not found]   ` <f8106fe7-a2b8-d106-3061-4d888124f4b0@cornell.edu>
     [not found]     ` <20210826062934.54f2f2216021c095bb7ba13b@nifty.ne.jp>
     [not found]       ` <d0a8c57d-1ed1-6b4f-c6e7-cbe0e2ec8a1c@cornell.edu>
     [not found]         ` <3b560051-ab27-f392-ca4b-d1fd9b5733b0@cornell.edu>
     [not found]           ` <20210827202440.47706fc2fc07c5e9a1bc0047@nifty.ne.jp>
     [not found]             ` <4f2cb5f3-ce9c-c617-f65f-841a5eca096e@cornell.edu>
     [not found]               ` <20210828022111.91ef5b4ff24f6da9fadb489e@nifty.ne.jp>
     [not found]                 ` <YSn3L0W1M527utK0@calimero.vinschen.de>
     [not found]                   ` <20210828184102.f2206a8a9e5fe5cf24bf5e45@nifty.ne.jp>
     [not found]                     ` <YSok0PoCQn2TPPrn@calimero.vinschen.de>
     [not found]                       ` <20210829004346.c2f80469abc3a07fd4b2918d@nifty.ne.jp>
     [not found]                         ` <e8caa02f-be85-33bc-3f09-347c1cdb0923@cornell.edu>
     [not found]                           ` <20210829174124.0c1ae6c16a3e8da1f490abc7@nifty.ne.jp>
     [not found]                             ` <6e9bb35e-6f4f-cf78-e515-549da487b5ef@cornell.edu>
2021-08-30  7:57                               ` Corinna Vinschen
     [not found]                     ` <20210829180729.48b4e877f773cb3980c5766d@nifty.ne.jp>
     [not found]                       ` <789f056a-f164-d71d-1dc9-230f5a41846d@cornell.edu>
2021-08-30  8:27                         ` Corinna Vinschen
2021-08-30 13:00                           ` Corinna Vinschen
2021-08-30 13:20                             ` Corinna Vinschen
2021-08-30 13:41                               ` Ken Brown
2021-08-30 14:12                                 ` Corinna Vinschen
2021-08-30 14:52                                   ` Ken Brown
2021-08-30 15:15                                     ` Corinna Vinschen
     [not found]                         ` <20210830043756.8aa0ada77db0bfbbe3889f62@nifty.ne.jp>
     [not found]                           ` <47e5dd74-b940-f305-fd5a-c6c9d8f41305@cornell.edu>
2021-08-30  8:48                             ` Corinna Vinschen
     [not found]                       ` <c62d18df-ab7a-7233-62ee-29a8eced5353@cornell.edu>
     [not found]                         ` <20210830091314.f9a2cb71794d0f68cdb5eba7@nifty.ne.jp>
     [not found]                           ` <20210830092259.52f7d54fc3fa340738373af4@nifty.ne.jp>
     [not found]                             ` <d217ef03-7858-5e22-0aa6-f0507eedd9da@cornell.edu>
     [not found]                               ` <20210830170204.fa91eaf110f310f13b67abc3@nifty.ne.jp>
2021-08-30 10:20                                 ` Corinna Vinschen
2021-08-30 10:38                                   ` Corinna Vinschen
2021-08-30 12:04                                   ` Takashi Yano
2021-08-30 12:55                                     ` Corinna Vinschen
2021-08-30 13:31                                       ` Corinna Vinschen
2021-08-31  8:50                                         ` Takashi Yano
2021-08-30 13:51                                       ` Ken Brown
2021-08-30 15:00                                         ` Ken Brown
2021-08-30 15:19                                           ` Corinna Vinschen
2021-08-30 15:43                                             ` Ken Brown
2021-08-31  9:43                                               ` Corinna Vinschen
2021-08-31  8:52                                             ` Takashi Yano
2021-08-31  9:04                                               ` Corinna Vinschen
2021-08-31 11:05                                                 ` Takashi Yano
2021-08-31 15:20                                                   ` Corinna Vinschen
2021-09-01  2:39                                                     ` Takashi Yano
2021-09-01  8:03                                                       ` Corinna Vinschen
2021-09-01  8:13                                                         ` Corinna Vinschen
2021-08-30 13:36                               ` Ken Brown
2021-08-30 14:05                                 ` Corinna Vinschen
2021-08-30 15:53                                   ` Corinna Vinschen
2021-08-30 17:00                                     ` Corinna Vinschen
2021-08-30 17:11                                       ` Corinna Vinschen
2021-08-30 18:59                                       ` Ken Brown
2021-08-30 19:12                                         ` Ken Brown
2021-08-30 20:21                                         ` Corinna Vinschen
2021-08-30 20:14                                       ` Corinna Vinschen
2021-08-30 20:47                                         ` Ken Brown
2021-08-31  8:55                                         ` Takashi Yano
2021-08-31  9:08                                           ` Corinna Vinschen
2021-08-31  9:25                                             ` Takashi Yano
2021-08-31 10:05                                               ` Corinna Vinschen
2021-08-31 10:18                                                 ` Corinna Vinschen
2021-08-31 11:45                                                   ` Takashi Yano
2021-08-31 12:31                                                     ` Takashi Yano
2021-08-31 15:08                                                       ` Corinna Vinschen
2021-08-31 12:33                                                     ` Ken Brown
2021-08-31 15:18                                                       ` Corinna Vinschen
2021-08-31 15:27                                                         ` Corinna Vinschen
2021-08-31 15:50                                                           ` Corinna Vinschen
2021-08-31 16:19                                                             ` Ken Brown
2021-08-31 16:38                                                               ` Ken Brown
2021-08-31 17:30                                                                 ` Corinna Vinschen
2021-08-31 18:54                                                                   ` Ken Brown
2021-08-31 19:51                                                                     ` Corinna Vinschen
2021-08-31 23:02                                                             ` Takashi Yano
2021-09-01  0:16                                                               ` Takashi Yano
2021-09-01  8:07                                                                 ` Corinna Vinschen
2021-09-01  8:23                                                                   ` Takashi Yano
2021-09-01  8:46                                                                     ` Corinna Vinschen
2021-09-01 12:56                                                                       ` Ken Brown
2021-09-01 13:52                                                                         ` Corinna Vinschen
2021-09-01 23:02                                                                           ` Ken Brown
2021-09-02  8:17                                                                             ` Corinna Vinschen
2021-09-02 13:01                                                                               ` Ken Brown
2021-09-02 19:00                                                                                 ` Corinna Vinschen
2021-09-02 19:34                                                                                   ` Ken Brown
2021-09-02 19:35                                                                                   ` Corinna Vinschen
2021-09-02 20:19                                                                                     ` Ken Brown
2021-09-03  9:12                                                                                       ` Corinna Vinschen
2021-09-03 19:00                                                                                         ` Ken Brown
2021-09-03 19:53                                                                                           ` Ken Brown
2021-09-03 19:54                                                                                           ` Corinna Vinschen
2021-09-03 20:05                                                                                             ` Ken Brown
2021-09-03 10:00                                                                                     ` Takashi Yano
2021-09-03 10:13                                                                                       ` Takashi Yano
2021-09-03 11:31                                                                                         ` Corinna Vinschen
2021-09-03 11:41                                                                                           ` Corinna Vinschen
2021-09-03 12:13                                                                                             ` Ken Brown
2021-09-03 15:00                                                                                               ` Corinna Vinschen
2021-09-03 15:14                                                                                                 ` Ken Brown
2021-09-03 15:17                                                                                                   ` Corinna Vinschen
2021-09-03 12:22                                                                                             ` Takashi Yano
2021-09-03 13:27                                                                                               ` Ken Brown
2021-09-03 15:37                                                                                               ` Corinna Vinschen
2021-09-04 12:02                                                                                                 ` Takashi Yano
2021-09-04 12:37                                                                                                   ` Takashi Yano
2021-09-04 14:04                                                                                                     ` Ken Brown
2021-09-04 23:15                                                                                                       ` Takashi Yano
2021-09-05 13:40                                                                                                         ` Takashi Yano
2021-09-05 13:50                                                                                                           ` Takashi Yano
2021-09-05 18:47                                                                                                             ` Ken Brown
2021-09-05 19:42                                                                                                               ` Takashi Yano
2021-09-05 20:09                                                                                                               ` Takashi Yano
2021-09-05 20:27                                                                                                                 ` Ken Brown
2021-09-06  8:13                                                                                                                 ` Corinna Vinschen
2021-09-06 11:16                                                                                                                   ` Takashi Yano
2021-09-06 12:49                                                                                                                     ` Corinna Vinschen
2021-09-06 13:16                                                                                                                       ` Takashi Yano
2021-09-06 16:08                                                                                                                         ` Corinna Vinschen
2021-09-06 23:39                                                                                                                           ` Takashi Yano
2021-09-07  9:14                                                                                                                             ` Corinna Vinschen
2021-09-07 11:03                                                                                                                               ` Takashi Yano
2021-09-07 16:14                                                                                                                       ` Ken Brown
2021-09-07 18:26                                                                                                                         ` Corinna Vinschen
2021-09-03 10:38                                                                                       ` Takashi Yano
2021-09-08 11:32                                                                                     ` Takashi Yano
2021-09-08 11:55                                                                                       ` Corinna Vinschen
2021-09-08 12:33                                                                                         ` Takashi Yano
2021-09-08 17:43                                                                                         ` Ken Brown
2021-09-08 18:28                                                                                           ` Corinna Vinschen
2021-09-02  8:15                                                                       ` Takashi Yano
2021-09-02 18:54                                                                         ` Corinna Vinschen
2021-09-07  3:26             ` Takashi Yano
2021-09-07 10:50               ` Takashi Yano
2021-09-08  0:07                 ` Takashi Yano
2021-09-08  4:11                   ` Takashi Yano
2021-09-08  9:01                     ` Takashi Yano
2021-09-08  9:01                     ` Corinna Vinschen
2021-09-08  9:26                       ` Corinna Vinschen
2021-09-08  9:45                         ` Takashi Yano
2021-09-08 10:04                           ` Corinna Vinschen
2021-09-08 10:45                             ` Takashi Yano
2021-09-08 10:51                               ` Corinna Vinschen
2021-09-09  3:21                                 ` Takashi Yano
2021-09-09  9:37                                   ` Corinna Vinschen
2021-09-09 10:55                                     ` Takashi Yano
2021-09-09 11:41                                       ` Corinna Vinschen
2021-09-08  9:37                       ` Takashi Yano
2021-09-09  3:41               ` Takashi Yano
2021-09-09  8:05                 ` Takashi Yano
2021-09-09 12:19                   ` Takashi Yano
2021-09-09 12:42                     ` Takashi Yano
2021-09-09 21:53                       ` Takashi Yano
2021-09-10  3:41                         ` Takashi Yano
2021-09-10 10:57                       ` Ken Brown
2021-09-10 15:17                         ` Ken Brown
2021-09-10 15:26                           ` Corinna Vinschen
2021-09-10 22:57                           ` Takashi Yano
2021-09-11  2:17                             ` Ken Brown
2021-09-11  2:35                               ` Takashi Yano
2021-09-11 13:12                                 ` Ken Brown
2021-09-12  6:23                                   ` Takashi Yano
2021-09-12 14:39                                     ` Ken Brown
2021-09-13  9:11                                       ` Corinna Vinschen
2021-09-13 12:30                                         ` Ken Brown
2021-09-12  8:48                                   ` Takashi Yano
2021-09-12 11:04                                     ` Takashi Yano
2021-09-12 15:10                                       ` Ken Brown
2021-09-12 21:46                                         ` Ken Brown
2021-09-12 23:54                                           ` Takashi Yano
2021-09-13  2:19                                             ` Ken Brown
2021-09-13  8:40                                             ` Takashi Yano
2021-09-13 12:51                                               ` Ken Brown
2021-09-13 17:05                                                 ` Ken Brown
2021-09-13  9:42                                           ` Corinna Vinschen
2021-09-13 13:03                                             ` Ken Brown
2021-09-13 18:39                                               ` Takashi Yano
2021-09-12 23:41                                         ` Takashi Yano
2021-09-13 17:42                                       ` Ken Brown
2021-09-13 18:54                                         ` Takashi Yano
2021-09-13 18:32                                       ` Corinna Vinschen
2021-09-13 19:37                                         ` Takashi Yano
2021-09-13 20:15                                           ` Corinna Vinschen
2021-09-14  8:07                                             ` Takashi Yano
2021-09-14  8:47                                               ` Corinna Vinschen
2021-09-14 12:38                                                 ` Ken Brown
2021-09-14 14:15                                                   ` Corinna Vinschen
2021-09-14  8:08                                           ` Takashi Yano [this message]
2021-09-14  9:03                                             ` Corinna Vinschen
2021-09-14  9:56                                               ` Takashi Yano
2021-09-14 10:19                                                 ` Takashi Yano
2021-09-14 11:03                                                   ` Corinna Vinschen
2021-09-14 12:05                                                     ` Takashi Yano
2021-09-14 14:17                                                       ` Corinna Vinschen
2021-09-14 22:14                                                       ` Ken Brown
2021-09-15  0:21                                                         ` Takashi Yano
2021-09-15  0:44                                                           ` Takashi Yano
2021-09-15  0:59                                                             ` Takashi Yano
2021-09-15  9:57                                                               ` Corinna Vinschen
2021-09-15 10:48                                                                 ` Takashi Yano
2021-09-15 10:58                                                                   ` Takashi Yano
2021-09-15 11:34                                                                     ` Corinna Vinschen
2021-09-15 11:40                                                                       ` Corinna Vinschen
2021-09-15 11:13                                                                   ` Corinna Vinschen
2021-09-15 11:41                                                                     ` Ken Brown
2021-09-15 11:49                                                                       ` Corinna Vinschen
2021-09-15 11:54                                                                     ` Takashi Yano
2021-09-15 12:20                                                                       ` Corinna Vinschen
2021-09-15 13:04                                                                         ` Takashi Yano
2021-09-15 13:42                                                                           ` Corinna Vinschen
2021-09-15 16:22                                                                             ` Ken Brown
2021-09-15 17:09                                                                               ` Ken Brown
2021-09-16  0:22                                                                                 ` Takashi Yano
2021-09-16  2:28                                                                                   ` Ken Brown
2021-09-16  9:09                                                                                 ` Takashi Yano
2021-09-16 13:02                                                                                   ` Takashi Yano
2021-09-16 13:25                                                                                     ` Corinna Vinschen
2021-09-16 14:27                                                                                       ` Takashi Yano
2021-09-16 15:01                                                                                         ` Corinna Vinschen
2021-09-16 15:46                                                                                           ` Ken Brown
2021-09-16 16:02                                                                                             ` Ken Brown
2021-09-16 19:42                                                                                               ` Takashi Yano
2021-09-16 20:28                                                                                                 ` Ken Brown
2021-09-16 19:48                                                                                               ` Ken Brown
2021-09-16 20:01                                                                                                 ` Takashi Yano
2021-09-17  2:25                                                                                                   ` Ken Brown
2021-09-17  8:31                                                                                                     ` Takashi Yano
2021-09-17 11:16                                                                                                       ` Ken Brown
2021-09-17 16:23                                                                                                         ` Takashi Yano
2021-09-17 17:08                                                                                                           ` Ken Brown
2021-09-17 17:39                                                                                                             ` Jon Turney
2021-09-17 17:43                                                                                                             ` Takashi Yano
2021-09-17 19:53                                                                                                               ` Ken Brown
2021-09-18  1:30                                                                                                                 ` Takashi Yano
2021-09-18  2:07                                                                                                                   ` Ken Brown
2021-09-18  2:10                                                                                                                     ` Ken Brown
2021-09-18  8:03                                                                                                                       ` Takashi Yano
2021-09-18 11:12                                                                                                                         ` Ken Brown
2021-09-18 11:35                                                                                                                           ` Takashi Yano
2021-09-18 14:11                                                                                                                             ` Jon Turney
2021-09-18 13:44                                                                                           ` Ken Brown
2021-09-19  1:31                                                                                             ` Takashi Yano
2021-09-19 14:35                                                                                               ` Ken Brown
2021-09-20  9:29                                                                                                 ` Takashi Yano
2021-09-16  0:13                                                                               ` Takashi Yano
2021-09-16  2:26                                                                                 ` Ken Brown
2021-09-13  9:07                                 ` Corinna Vinschen
2021-09-20 12:52                                   ` Takashi Yano
2021-09-20 19:14                                     ` Ken Brown
2021-09-20 21:09                                       ` Ken Brown
2021-09-20 21:21                                         ` Ken Brown
2021-09-20 21:27                                         ` Takashi Yano
2021-09-20 21:39                                           ` Ken Brown
2021-09-20 22:16                                             ` Takashi Yano
2021-09-20 22:46                                               ` Ken Brown
2021-09-20 22:50                                                 ` Ken Brown
2021-09-20 23:22                                                   ` Takashi Yano
2021-09-21  8:30                                                     ` Takashi Yano
2021-09-21  9:26                                                       ` Mark Geisert
2021-09-21 10:10                                                         ` Takashi Yano
2021-09-21 21:10                                                           ` Mark Geisert
2021-09-21 13:31                                                       ` Ken Brown
2021-09-21 15:36                                                         ` Takashi Yano
2021-09-21 18:51                                                           ` Ken Brown
2021-09-23  8:26                                                             ` Takashi Yano
2021-09-23 13:03                                                               ` Ken Brown
2021-09-23 15:03                                                                 ` Takashi Yano
2021-09-23 16:29                                                                   ` Ken Brown
2021-10-18 10:51                                                                   ` Corinna Vinschen
2021-10-18 12:02                                                                     ` Takashi Yano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210914170838.6393026ac3eaa4cd4e3d9618@nifty.ne.jp \
    --to=takashi.yano@nifty.ne.jp \
    --cc=cygwin-developers@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).