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.
This commit is contained in:
parent
f79a46112e
commit
e4e4537979
|
@ -1177,6 +1177,7 @@ class fhandler_pipe_fifo: public fhandler_base
|
||||||
protected:
|
protected:
|
||||||
size_t pipe_buf_size;
|
size_t pipe_buf_size;
|
||||||
HANDLE query_hdl;
|
HANDLE query_hdl;
|
||||||
|
virtual void release_select_sem (const char *) {};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
fhandler_pipe_fifo ();
|
fhandler_pipe_fifo ();
|
||||||
|
@ -1201,6 +1202,7 @@ class fhandler_pipe: public fhandler_pipe_fifo
|
||||||
private:
|
private:
|
||||||
HANDLE read_mtx;
|
HANDLE read_mtx;
|
||||||
pid_t popen_pid;
|
pid_t popen_pid;
|
||||||
|
void release_select_sem (const char *);
|
||||||
public:
|
public:
|
||||||
fhandler_pipe ();
|
fhandler_pipe ();
|
||||||
|
|
||||||
|
@ -1444,6 +1446,8 @@ class fhandler_fifo: public fhandler_pipe_fifo
|
||||||
void shared_fc_handler_updated (bool val)
|
void shared_fc_handler_updated (bool val)
|
||||||
{ shmem->shared_fc_handler_updated (val); }
|
{ shmem->shared_fc_handler_updated (val); }
|
||||||
|
|
||||||
|
void release_select_sem (const char *);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
fhandler_fifo ();
|
fhandler_fifo ();
|
||||||
~fhandler_fifo ()
|
~fhandler_fifo ()
|
||||||
|
|
|
@ -1185,6 +1185,22 @@ fhandler_fifo::take_ownership (DWORD timeout)
|
||||||
return ret;
|
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
|
void __reg3
|
||||||
fhandler_fifo::raw_read (void *in_ptr, size_t& len)
|
fhandler_fifo::raw_read (void *in_ptr, size_t& len)
|
||||||
{
|
{
|
||||||
|
@ -1372,7 +1388,7 @@ out:
|
||||||
fifo_client_unlock ();
|
fifo_client_unlock ();
|
||||||
reading_unlock ();
|
reading_unlock ();
|
||||||
if (select_sem)
|
if (select_sem)
|
||||||
ReleaseSemaphore (select_sem, get_obj_handle_count (select_sem), NULL);
|
release_select_sem ("raw_read");
|
||||||
}
|
}
|
||||||
|
|
||||||
int __reg2
|
int __reg2
|
||||||
|
@ -1483,6 +1499,11 @@ fhandler_fifo::cancel_reader_thread ()
|
||||||
int
|
int
|
||||||
fhandler_fifo::close ()
|
fhandler_fifo::close ()
|
||||||
{
|
{
|
||||||
|
if (select_sem)
|
||||||
|
{
|
||||||
|
release_select_sem ("close");
|
||||||
|
NtClose (select_sem);
|
||||||
|
}
|
||||||
if (writer)
|
if (writer)
|
||||||
{
|
{
|
||||||
nwriters_lock ();
|
nwriters_lock ();
|
||||||
|
@ -1574,11 +1595,6 @@ fhandler_fifo::close ()
|
||||||
NtClose (write_ready);
|
NtClose (write_ready);
|
||||||
if (writer_opening)
|
if (writer_opening)
|
||||||
NtClose (writer_opening);
|
NtClose (writer_opening);
|
||||||
if (select_sem)
|
|
||||||
{
|
|
||||||
ReleaseSemaphore (select_sem, get_obj_handle_count (select_sem), NULL);
|
|
||||||
NtClose (select_sem);
|
|
||||||
}
|
|
||||||
if (nohandle ())
|
if (nohandle ())
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
|
|
|
@ -233,6 +233,22 @@ fhandler_pipe::get_proc_fd_name (char *buf)
|
||||||
return 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
|
void __reg3
|
||||||
fhandler_pipe::raw_read (void *ptr, size_t& len)
|
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;
|
ptr = ((char *) ptr) + nbytes_now;
|
||||||
nbytes += nbytes_now;
|
nbytes += nbytes_now;
|
||||||
if (select_sem && nbytes_now > 0)
|
if (select_sem && nbytes_now > 0)
|
||||||
ReleaseSemaphore (select_sem,
|
release_select_sem ("raw_read");
|
||||||
get_obj_handle_count (select_sem), NULL);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -496,8 +511,7 @@ fhandler_pipe_fifo::raw_write (const void *ptr, size_t len)
|
||||||
ptr = ((char *) ptr) + nbytes_now;
|
ptr = ((char *) ptr) + nbytes_now;
|
||||||
nbytes += nbytes_now;
|
nbytes += nbytes_now;
|
||||||
if (select_sem && nbytes_now > 0)
|
if (select_sem && nbytes_now > 0)
|
||||||
ReleaseSemaphore (select_sem,
|
release_select_sem ("raw_write");
|
||||||
get_obj_handle_count (select_sem), NULL);
|
|
||||||
/* 0 bytes returned? EAGAIN. See above. */
|
/* 0 bytes returned? EAGAIN. See above. */
|
||||||
if (NT_SUCCESS (status) && nbytes == 0)
|
if (NT_SUCCESS (status) && nbytes == 0)
|
||||||
set_errno (EAGAIN);
|
set_errno (EAGAIN);
|
||||||
|
@ -591,13 +605,13 @@ fhandler_pipe::dup (fhandler_base *child, int flags)
|
||||||
int
|
int
|
||||||
fhandler_pipe::close ()
|
fhandler_pipe::close ()
|
||||||
{
|
{
|
||||||
if (read_mtx)
|
|
||||||
CloseHandle (read_mtx);
|
|
||||||
if (select_sem)
|
if (select_sem)
|
||||||
{
|
{
|
||||||
ReleaseSemaphore (select_sem, get_obj_handle_count (select_sem), NULL);
|
release_select_sem ("close");
|
||||||
CloseHandle (select_sem);
|
CloseHandle (select_sem);
|
||||||
}
|
}
|
||||||
|
if (read_mtx)
|
||||||
|
CloseHandle (read_mtx);
|
||||||
if (query_hdl)
|
if (query_hdl)
|
||||||
CloseHandle (query_hdl);
|
CloseHandle (query_hdl);
|
||||||
return fhandler_base::close ();
|
return fhandler_base::close ();
|
||||||
|
|
Loading…
Reference in New Issue