Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Yano <takashi.yano@nifty.ne.jp>2021-09-14 12:50:49 +0300
committerCorinna Vinschen <corinna@vinschen.de>2021-09-14 14:02:51 +0300
commite4e45379796f999a07029df3bd15918105a751e3 (patch)
treed35992b9c0625d60df44a24bad2f91b9e3c75374
parentf79a46112e7c43858203536955ad41af701b4a0f (diff)
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.
-rw-r--r--winsup/cygwin/fhandler.h4
-rw-r--r--winsup/cygwin/fhandler_fifo.cc28
-rw-r--r--winsup/cygwin/fhandler_pipe.cc28
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 b7d4cb5cc..7e5ab328c 100644
--- a/winsup/cygwin/fhandler_pipe.cc
+++ b/winsup/cygwin/fhandler_pipe.cc
@@ -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 ();