Cygwin: FIFO: add a shared fifo_client_handler list
This is in a new shared memory section. We will use it for temporary storage of the owner's fc_handler list when we need to change owner. The new owner can then duplicate the pipe handles from that list before taking ownership. Add several shared data members and methods that are needed for the duplication process Add methods update_my_handlers and update_shared_handlers that carry out the duplication. Allow the shared list to grow dynamically, up to a point. Do this by initially reserving a block of memory (currently 100 pages) and only committing pages as needed. Add methods create_shared_fc_handler, reopen_shared_fc_handler, and remap_shared_fc_handler to create the new shared memory section, reopen it, and commit new pages. The first is called in open, the second is called in dup/fork/exec, and the third is called in update_shared_handlers if more shared memory is needed. Modify the fifo_reader_thread function to call update_my_handlers when it finds that there is no owner. Also make it call update_shared_handlers when the owner's thread terminates, so that the new owner will have an accurate shared fc_handler list from which to duplicate. For convenience, add new methods cleanup_handlers and close_all_handlers. And add an optional arg to add_client_handler that allows it to create a new fifo_client_handler without creating a new pipe instance.
This commit is contained in:
@ -1323,17 +1323,33 @@ struct fifo_reader_id_t
|
||||
class fifo_shmem_t
|
||||
{
|
||||
LONG _nreaders;
|
||||
fifo_reader_id_t _owner;
|
||||
fifo_reader_id_t _owner, _prev_owner;
|
||||
af_unix_spinlock_t _owner_lock;
|
||||
|
||||
/* Info about shared memory block used for temporary storage of the
|
||||
owner's fc_handler list. */
|
||||
LONG _sh_nhandlers, _sh_shandlers, _sh_fc_handler_committed;
|
||||
|
||||
public:
|
||||
int inc_nreaders () { return (int) InterlockedIncrement (&_nreaders); }
|
||||
int dec_nreaders () { return (int) InterlockedDecrement (&_nreaders); }
|
||||
|
||||
fifo_reader_id_t get_owner () const { return _owner; }
|
||||
void set_owner (fifo_reader_id_t fr_id) { _owner = fr_id; }
|
||||
fifo_reader_id_t get_prev_owner () const { return _prev_owner; }
|
||||
void set_prev_owner (fifo_reader_id_t fr_id) { _prev_owner = fr_id; }
|
||||
|
||||
void owner_lock () { _owner_lock.lock (); }
|
||||
void owner_unlock () { _owner_lock.unlock (); }
|
||||
|
||||
int get_shared_nhandlers () const { return (int) _sh_nhandlers; }
|
||||
void set_shared_nhandlers (int n) { InterlockedExchange (&_sh_nhandlers, n); }
|
||||
int get_shared_shandlers () const { return (int) _sh_shandlers; }
|
||||
void set_shared_shandlers (int n) { InterlockedExchange (&_sh_shandlers, n); }
|
||||
size_t get_shared_fc_handler_committed () const
|
||||
{ return (size_t) _sh_fc_handler_committed; }
|
||||
void set_shared_fc_handler_committed (size_t n)
|
||||
{ InterlockedExchange (&_sh_fc_handler_committed, (LONG) n); }
|
||||
};
|
||||
|
||||
class fhandler_fifo: public fhandler_base
|
||||
@ -1360,24 +1376,47 @@ class fhandler_fifo: public fhandler_base
|
||||
|
||||
HANDLE shmem_handle;
|
||||
fifo_shmem_t *shmem;
|
||||
HANDLE shared_fc_hdl;
|
||||
/* Dynamically growing array in shared memory. */
|
||||
fifo_client_handler *shared_fc_handler;
|
||||
|
||||
bool __reg2 wait (HANDLE);
|
||||
static NTSTATUS npfs_handle (HANDLE &);
|
||||
HANDLE create_pipe_instance ();
|
||||
NTSTATUS open_pipe (HANDLE&);
|
||||
NTSTATUS wait_open_pipe (HANDLE&);
|
||||
int add_client_handler ();
|
||||
int add_client_handler (bool new_pipe_instance = true);
|
||||
void delete_client_handler (int);
|
||||
void cleanup_handlers ();
|
||||
void close_all_handlers ();
|
||||
void cancel_reader_thread ();
|
||||
void record_connection (fifo_client_handler&,
|
||||
fifo_client_connect_state = fc_connected);
|
||||
|
||||
int create_shmem ();
|
||||
int reopen_shmem ();
|
||||
int create_shared_fc_handler ();
|
||||
int reopen_shared_fc_handler ();
|
||||
int remap_shared_fc_handler (size_t);
|
||||
|
||||
int inc_nreaders () { return shmem->inc_nreaders (); }
|
||||
int dec_nreaders () { return shmem->dec_nreaders (); }
|
||||
|
||||
fifo_reader_id_t get_prev_owner () const { return shmem->get_prev_owner (); }
|
||||
void set_prev_owner (fifo_reader_id_t fr_id)
|
||||
{ shmem->set_prev_owner (fr_id); }
|
||||
|
||||
int get_shared_nhandlers () { return shmem->get_shared_nhandlers (); }
|
||||
void set_shared_nhandlers (int n) { shmem->set_shared_nhandlers (n); }
|
||||
int get_shared_shandlers () { return shmem->get_shared_shandlers (); }
|
||||
void set_shared_shandlers (int n) { shmem->set_shared_shandlers (n); }
|
||||
size_t get_shared_fc_handler_committed () const
|
||||
{ return shmem->get_shared_fc_handler_committed (); }
|
||||
void set_shared_fc_handler_committed (size_t n)
|
||||
{ shmem->set_shared_fc_handler_committed (n); }
|
||||
int update_my_handlers ();
|
||||
int update_shared_handlers ();
|
||||
|
||||
public:
|
||||
fhandler_fifo ();
|
||||
bool hit_eof ();
|
||||
|
Reference in New Issue
Block a user