Cygwin: FIFO: synchronize the fifo_reader and fifosel threads

The fifo_reader thread function and the function select.cc:peek_fifo()
can both change the state of a fifo_client_handler.  These changes are
made under fifo_client_lock, so there is no race, but the changes can
still be incompatible.

Add code to make sure that only one of these functions can change the
state from its initial fc_listening state.  Whichever function does
this calls the fhandler_fifo::record_connection method, which is now
public so that peek_fifo can call it.

Slightly modify that method to make it suitable for being called by
peek_fifo.

Make a few other small changes to the fifo_reader thread function to
change how it deals with the STATUS_PIPE_CLOSING value that can
(rarely) be returned by NtFsControlFile.

Add commentary to fhandler_fifo.cc to explain fifo_client connect
states and where they can be changed.
This commit is contained in:
Ken Brown
2020-08-03 09:38:08 -04:00
parent 251624a352
commit 0fda55133a
3 changed files with 60 additions and 9 deletions

View File

@@ -877,10 +877,13 @@ peek_fifo (select_record *s, bool from_select)
for (int i = 0; i < fh->get_nhandlers (); i++)
{
fifo_client_handler &fc = fh->get_fc_handler (i);
fc.query_and_set_state ();
fifo_client_connect_state prev_state = fc.query_and_set_state ();
if (fc.get_state () >= fc_connected)
{
nconnected++;
if (prev_state == fc_listening)
/* The connection was not recorded by the fifo_reader_thread. */
fh->record_connection (fc, false);
if (fc.get_state () == fc_input_avail)
{
select_printf ("read: %s, ready for read", fh->get_name ());