Cygwin: FIFO: designate one reader as owner
Among all the open readers of a FIFO, one is declared to be the owner. This is the only reader that listens for client connections, and it is the only one that has an accurate fc_handler list. Add shared data and methods for getting and setting the owner, as well as a lock to prevent more than one reader from accessing these data simultaneously. Modify the fifo_reader_thread so that it checks the owner at the beginning of its loop. If there is no owner, it takes ownership. If there is an owner but it is a different reader, the thread just waits to be canceled. Otherwise, it listens for client connections as before. Remove the 'first' argument from create_pipe_instance. It is not needed, and it may be confusing in the future since only the owner knows whether a pipe instance is the first. When opening a reader, don't return until the fifo_reader_thread has time to set an owner. If the owner closes, indicate that there is no longer an owner. Clear the child's fc_handler list in dup, and don't bother duplicating the handles. The child never starts out as owner, so it can't use those handles. Do the same thing in fixup_after_fork in the close-on-exec case. In the non-close-on-exec case, the child inherits an fc_handler list that it can't use, but we can just leave it alone; the handles will be closed when the child is closed.
This commit is contained in:
@ -1324,10 +1324,17 @@ struct fifo_reader_id_t
|
||||
class fifo_shmem_t
|
||||
{
|
||||
LONG _nreaders;
|
||||
fifo_reader_id_t _owner;
|
||||
af_unix_spinlock_t _owner_lock;
|
||||
|
||||
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; }
|
||||
void owner_lock () { _owner_lock.lock (); }
|
||||
void owner_unlock () { _owner_lock.unlock (); }
|
||||
};
|
||||
|
||||
class fhandler_fifo: public fhandler_base
|
||||
@ -1356,7 +1363,7 @@ class fhandler_fifo: public fhandler_base
|
||||
|
||||
bool __reg2 wait (HANDLE);
|
||||
static NTSTATUS npfs_handle (HANDLE &);
|
||||
HANDLE create_pipe_instance (bool);
|
||||
HANDLE create_pipe_instance ();
|
||||
NTSTATUS open_pipe (HANDLE&);
|
||||
NTSTATUS wait_open_pipe (HANDLE&);
|
||||
int add_client_handler ();
|
||||
@ -1384,6 +1391,10 @@ public:
|
||||
void fifo_client_unlock () { _fifo_client_lock.unlock (); }
|
||||
|
||||
fifo_reader_id_t get_me () const { return me; }
|
||||
fifo_reader_id_t get_owner () const { return shmem->get_owner (); }
|
||||
void set_owner (fifo_reader_id_t fr_id) { shmem->set_owner (fr_id); }
|
||||
void owner_lock () { shmem->owner_lock (); }
|
||||
void owner_unlock () { shmem->owner_unlock (); }
|
||||
|
||||
int open (int, mode_t);
|
||||
off_t lseek (off_t offset, int whence);
|
||||
|
Reference in New Issue
Block a user