Cygwin: FIFO: allow fc_handler list to grow dynamically

Make fc_handler a pointer to malloc'd memory instead of a fixed-size
array.  The size is now a new data member 'shandlers'.  Call realloc
in add_client_handler if we need to grow the array.

free fc_handler in close.  As long as we're touching that code, also
remove an unneeded lock.
This commit is contained in:
Ken Brown 2020-04-02 13:47:18 -04:00
parent 606baf5566
commit c76ded2ca0
2 changed files with 26 additions and 21 deletions

View File

@ -1268,7 +1268,6 @@ public:
}; };
#define CYGWIN_FIFO_PIPE_NAME_LEN 47 #define CYGWIN_FIFO_PIPE_NAME_LEN 47
#define MAX_CLIENTS 64
/* The last three are the ones we try to read from. */ /* The last three are the ones we try to read from. */
enum fifo_client_connect_state enum fifo_client_connect_state
@ -1351,8 +1350,9 @@ class fhandler_fifo: public fhandler_base
UNICODE_STRING pipe_name; UNICODE_STRING pipe_name;
WCHAR pipe_name_buf[CYGWIN_FIFO_PIPE_NAME_LEN + 1]; WCHAR pipe_name_buf[CYGWIN_FIFO_PIPE_NAME_LEN + 1];
bool _maybe_eof; bool _maybe_eof;
fifo_client_handler fc_handler[MAX_CLIENTS]; fifo_client_handler *fc_handler; /* Dynamically growing array. */
int nhandlers; int shandlers; /* Size (capacity) of the array. */
int nhandlers; /* Number of elements in the array. */
af_unix_spinlock_t _fifo_client_lock; af_unix_spinlock_t _fifo_client_lock;
bool reader, writer, duplexer; bool reader, writer, duplexer;
size_t max_atomic_write; size_t max_atomic_write;

View File

@ -70,7 +70,8 @@ static NO_COPY fifo_reader_id_t null_fr_id = { .winpid = 0, .fh = NULL };
fhandler_fifo::fhandler_fifo (): fhandler_fifo::fhandler_fifo ():
fhandler_base (), fhandler_base (),
read_ready (NULL), write_ready (NULL), writer_opening (NULL), read_ready (NULL), write_ready (NULL), writer_opening (NULL),
cancel_evt (NULL), thr_sync_evt (NULL), _maybe_eof (false), nhandlers (0), cancel_evt (NULL), thr_sync_evt (NULL), _maybe_eof (false),
fc_handler (NULL), shandlers (0), nhandlers (0),
reader (false), writer (false), duplexer (false), reader (false), writer (false), duplexer (false),
max_atomic_write (DEFAULT_PIPEBUFSIZE), max_atomic_write (DEFAULT_PIPEBUFSIZE),
me (null_fr_id), shmem_handle (NULL), shmem (NULL) me (null_fr_id), shmem_handle (NULL), shmem (NULL)
@ -287,27 +288,28 @@ fhandler_fifo::wait_open_pipe (HANDLE& ph)
int int
fhandler_fifo::add_client_handler () fhandler_fifo::add_client_handler ()
{ {
int ret = -1;
fifo_client_handler fc; fifo_client_handler fc;
HANDLE ph = NULL; HANDLE ph = NULL;
if (nhandlers == MAX_CLIENTS) if (nhandlers >= shandlers)
{ {
set_errno (EMFILE); void *temp = realloc (fc_handler,
goto out; (shandlers += 64) * sizeof (fc_handler[0]));
if (!temp)
{
shandlers -= 64;
set_errno (ENOMEM);
return -1;
}
fc_handler = (fifo_client_handler *) temp;
} }
ph = create_pipe_instance (); ph = create_pipe_instance ();
if (!ph) if (!ph)
goto out; return -1;
else
{
ret = 0;
fc.h = ph; fc.h = ph;
fc.state = fc_listening; fc.state = fc_listening;
fc_handler[nhandlers++] = fc; fc_handler[nhandlers++] = fc;
} return 0;
out:
return ret;
} }
void void
@ -1067,10 +1069,10 @@ fhandler_fifo::close ()
NtClose (write_ready); NtClose (write_ready);
if (writer_opening) if (writer_opening)
NtClose (writer_opening); NtClose (writer_opening);
fifo_client_lock ();
for (int i = 0; i < nhandlers; i++) for (int i = 0; i < nhandlers; i++)
fc_handler[i].close (); fc_handler[i].close ();
fifo_client_unlock (); if (fc_handler)
free (fc_handler);
return fhandler_base::close (); return fhandler_base::close ();
} }
@ -1130,7 +1132,8 @@ fhandler_fifo::dup (fhandler_base *child, int flags)
fhf->fifo_client_unlock (); fhf->fifo_client_unlock ();
/* Clear fc_handler list; the child never starts as owner. */ /* Clear fc_handler list; the child never starts as owner. */
fhf->nhandlers = 0; fhf->nhandlers = fhf->shandlers = 0;
fhf->fc_handler = NULL;
if (!DuplicateHandle (GetCurrentProcess (), shmem_handle, if (!DuplicateHandle (GetCurrentProcess (), shmem_handle,
GetCurrentProcess (), &fhf->shmem_handle, GetCurrentProcess (), &fhf->shmem_handle,
@ -1206,6 +1209,8 @@ fhandler_fifo::fixup_after_exec ()
if (reopen_shmem () < 0) if (reopen_shmem () < 0)
api_fatal ("Can't reopen shared memory during exec, %E"); api_fatal ("Can't reopen shared memory during exec, %E");
fc_handler = NULL;
nhandlers = shandlers = 0;
me.winpid = GetCurrentProcessId (); me.winpid = GetCurrentProcessId ();
if (!(cancel_evt = create_event ())) if (!(cancel_evt = create_event ()))
api_fatal ("Can't create reader thread cancel event during exec, %E"); api_fatal ("Can't create reader thread cancel event during exec, %E");