Cygwin: FIFO: allow multiple writers

Introduce a 'fifo_client_handler' structure that can be used by a
reader to communicate with a writer using an instance of the named
pipe.  An fhandler_fifo opened for reading creates a thread that does
the following:

 - maintains a list of fifo_client_handlers
 - listens for_clients trying to connect
 - creates new pipe instances as needed so that there's always at
   least one available for connecting.

The pipe instances are initially created in blocking mode, but they
are set to be non-blocking after a connection is made.

fhandler_fifo::raw_read now loops through the connected clients and
reads from the first one that has data available.

New fhandler_fifo methods: add_client, listen_client,
listen_client_thread, check_listen_client_thread.

Replace the create_pipe method by create_pipe_instance, which allows
unlimited pipe instances.

New helper functions: create_event, set_pipe_non_blocking.
This commit is contained in:
Ken Brown
2019-03-22 19:30:37 +00:00
committed by Corinna Vinschen
parent 5955da96e2
commit 48d4cce3be
2 changed files with 367 additions and 32 deletions

View File

@ -1235,20 +1235,49 @@ public:
};
#define CYGWIN_FIFO_PIPE_NAME_LEN 47
#define MAX_CLIENTS 64
enum fifo_client_connect_state
{
fc_unknown,
fc_connecting,
fc_connected,
fc_invalid
};
struct fifo_client_handler
{
fhandler_base *fh;
fifo_client_connect_state state;
HANDLE connect_evt;
HANDLE dummy_evt; /* Never signaled. */
fifo_client_handler () : fh (NULL), state (fc_unknown), connect_evt (NULL),
dummy_evt (NULL) {}
int connect ();
int close ();
};
class fhandler_fifo: public fhandler_base
{
HANDLE read_ready;
HANDLE write_ready;
HANDLE listen_client_thr;
HANDLE lct_termination_evt;
UNICODE_STRING pipe_name;
WCHAR pipe_name_buf[CYGWIN_FIFO_PIPE_NAME_LEN + 1];
fifo_client_handler client[MAX_CLIENTS];
int nclients, nconnected;
bool __reg2 wait (HANDLE);
NTSTATUS npfs_handle (HANDLE &);
HANDLE create_pipe ();
HANDLE create_pipe_instance (bool);
NTSTATUS open_pipe ();
int disconnect_and_reconnect (int);
int add_client ();
bool listen_client ();
public:
fhandler_fifo ();
PUNICODE_STRING get_pipe_name ();
DWORD listen_client_thread ();
int open (int, mode_t);
off_t lseek (off_t offset, int whence);
int close ();