Cygwin: FIFO: code simplification

There are currently three functions that call NtQueryInformationFile
to determine the state of a pipe instance.  Do this only once, in a
new fifo_client_handler::set_state () function, and call that when
state information is needed.

Remove the fifo_client_handler methods pipe_state and get_state, which
are no longer needed.

Make fhandler_fifo::get_fc_handler return a reference, for use in
select.cc:peek_fifo.

Make other small changes to ensure that this commit doesn't change any
decisions based on the state of a fifo_client_handler.

The tricky part is interpreting FILE_PIPE_CLOSING_STATE, which we
translate to fc_closing.  Our current interpretation, which is not
changing as a result of this commit, is that the writer at the other
end of the pipe instance is viewed as still connected from the point
of view of raw_read and determining EOF.

But it is not viewed as still connected if we are deciding whether to
unblock a new reader that is trying to open.
This commit is contained in:
Ken Brown
2020-05-09 17:25:39 -04:00
parent 2125ca8a69
commit 1f27345947
3 changed files with 44 additions and 67 deletions

View File

@ -343,7 +343,7 @@ fhandler_fifo::delete_client_handler (int i)
(nhandlers - i) * sizeof (fc_handler[i]));
}
/* Delete invalid handlers. */
/* Delete handlers that we will never read from. */
void
fhandler_fifo::cleanup_handlers ()
{
@ -351,7 +351,7 @@ fhandler_fifo::cleanup_handlers ()
while (i < nhandlers)
{
if (fc_handler[i].state < fc_connected)
if (fc_handler[i].state < fc_closing)
delete_client_handler (i);
else
i++;
@ -417,9 +417,6 @@ fhandler_fifo::update_my_handlers (bool from_exec)
for (int i = 0; i < get_shared_nhandlers (); i++)
{
/* Should never happen. */
if (shared_fc_handler[i].state < fc_connected)
continue;
if (add_client_handler (false) < 0)
api_fatal ("Can't add client handler, %E");
fifo_client_handler &fc = fc_handler[nhandlers - 1];
@ -462,30 +459,9 @@ fhandler_fifo::check_write_ready ()
{
bool set = false;
fifo_client_lock ();
for (int i = 0; i < nhandlers && !set; i++)
switch (fc_handler[i].pipe_state ())
{
case FILE_PIPE_CONNECTED_STATE:
fc_handler[i].state = fc_connected;
set = true;
break;
case FILE_PIPE_INPUT_AVAILABLE_STATE:
fc_handler[i].state = fc_input_avail;
set = true;
break;
case FILE_PIPE_DISCONNECTED_STATE:
fc_handler[i].state = fc_disconnected;
break;
case FILE_PIPE_LISTENING_STATE:
fc_handler[i].state = fc_listening;
case FILE_PIPE_CLOSING_STATE:
fc_handler[i].state = fc_closing;
default:
fc_handler[i].state = fc_error;
break;
}
fifo_client_unlock ();
if (fc_handler[i].set_state () >= fc_connected)
set = true;
if (set || IsEventSignalled (writer_opening))
SetEvent (write_ready);
else
@ -656,13 +632,13 @@ fhandler_fifo::fifo_reader_thread_func ()
default:
break;
}
fifo_client_unlock ();
if (ph)
NtClose (ph);
if (update && update_shared_handlers () < 0)
api_fatal ("Can't update shared handlers, %E");
if (check)
check_write_ready ();
fifo_client_unlock ();
if (cancel)
goto canceled;
}
@ -1307,7 +1283,7 @@ fhandler_fifo::raw_read (void *in_ptr, size_t& len)
int nconnected = 0;
fifo_client_lock ();
for (int i = 0; i < nhandlers; i++)
if (fc_handler[i].state >= fc_connected)
if (fc_handler[i].state >= fc_closing)
{
NTSTATUS status;
IO_STATUS_BLOCK io;
@ -1411,25 +1387,45 @@ fhandler_fifo::close_all_handlers ()
nhandlers = 0;
}
int
fifo_client_handler::pipe_state ()
fifo_client_connect_state
fifo_client_handler::set_state ()
{
IO_STATUS_BLOCK io;
FILE_PIPE_LOCAL_INFORMATION fpli;
NTSTATUS status;
if (!h)
return (state = fc_unknown);
status = NtQueryInformationFile (h, &io, &fpli,
sizeof (fpli), FilePipeLocalInformation);
if (!NT_SUCCESS (status))
{
debug_printf ("NtQueryInformationFile status %y", status);
__seterrno_from_nt_status (status);
return -1;
state = fc_error;
}
else if (fpli.ReadDataAvailable > 0)
return FILE_PIPE_INPUT_AVAILABLE_STATE;
state = fc_input_avail;
else
return fpli.NamedPipeState;
switch (fpli.NamedPipeState)
{
case FILE_PIPE_DISCONNECTED_STATE:
state = fc_disconnected;
break;
case FILE_PIPE_LISTENING_STATE:
state = fc_listening;
break;
case FILE_PIPE_CONNECTED_STATE:
state = fc_connected;
break;
case FILE_PIPE_CLOSING_STATE:
state = fc_closing;
break;
default:
state = fc_error;
break;
}
return state;
}
void