]> sourceware.org Git - newlib-cygwin.git/commitdiff
Cygwin: pipe, fifo: Release select_sem semaphore as much as needed.
authorTakashi Yano <takashi.yano@nifty.ne.jp>
Tue, 14 Sep 2021 09:50:49 +0000 (18:50 +0900)
committerCorinna Vinschen <corinna@vinschen.de>
Tue, 14 Sep 2021 11:02:51 +0000 (13:02 +0200)
- 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
winsup/cygwin/fhandler_fifo.cc
winsup/cygwin/fhandler_pipe.cc

index db2325144a22ca0cc51df9d5757455bee2de0320..9580a698c5f93063439059578cd503692e8ab0b4 100644 (file)
@@ -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 ()
index 37498f54773c358815da2c875c93facab550c188..489ba528c5ead7757ebddfd218b1fb23b249e8c9 100644 (file)
@@ -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
index b7d4cb5ccf3245546f3a462bae169fbce582a8fa..7e5ab328c1b7461d78ac04415c27d844b3d8f7e7 100644 (file)
@@ -233,6 +233,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)
 {
@@ -324,8 +340,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
        {
@@ -496,8 +511,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)
            set_errno (EAGAIN);
@@ -591,13 +605,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 ();
This page took 0.039407 seconds and 5 git commands to generate.