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:
parent
606baf5566
commit
c76ded2ca0
|
@ -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;
|
||||||
|
|
|
@ -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");
|
||||||
|
|
Loading…
Reference in New Issue