Hi Folks:
I am experiencing an intermittent problem with uv_poll_init() after the
successful establishment and release
of multiple concurrent TCP connections. I am not sure if this problem is
due to a bug, which may
be corrected in another Libuv release, or if I am doing something wrong
when releasing the poll handle.
Do you have insight about the cause ? The details I consider most important
follow.
The uv_poll_t callback function reads incoming TCP data as follows.
iff(events & UV_READABLE)
{
CONN_DESC *cdesc = (CONN_DESC *) poll_handle->data;
n = recv(cdesc->fd, cdesc->rx_buf, RX_BUF_SIZE, MSG_DONTWAIT);
NOTE: I am using Libuv version 1.41.0 running on Ubuntu Linux version 15.04.
The problem is that uv_poll_init() fails, normally with the EEXIST or EBADF
error code, and
my investigation indicates the uv_loop_t Poll_Loop.watchers[N] field is not
NULL when it should be,
where N is TCP socket descriptor. It occurs immediately after the uv_poll_t
poll_handle is allocated.
(There is exactly one TCP socket descriptor per poll handle.) The call to
uv_poll_init() is as follows
and the socket descriptor is obtained with uv_fileno().
if( (r = uv_poll_init(&Poll_Loop, poll_handle, cdesc->fd)) != 0)
{
fatal_error(LOG_CRIT, "IO_TASK: POLL_PROXY - Polling
Initialization Error %d, %s",
r, uv_err_name(r));
}
It occurs in the IO_Task() thread when there multiple TCP socket
descriptors are in use. The IO_task
releases the poll_handle with the following code sequence when it is
notified that polling should stop
via a Libuv async. message from the Protocol_Task() thread.
if( (r = uv_poll_stop(poll_handle)) )
{
fatal_error(LOG_CRIT, "IO_TASK: POLL_PROXY - Poll Stop Error %d,
%s",
r, uv_err_name(r) );
}
poll_handle->data = (void *) cdesc;
uv_close((uv_handle_t *) poll_handle, async_close_callback);
The actual release occurs in async_close_callback() as follows and the
Protocol_Task() releases the
TCP socket decriptor with a normal Linux close() after it receives the
T_DISMANTLE response message.
VFREE((UCHAR *) handle);
//
// Send a notification message to the Protocol_Task.
//
msg = MSG_ALLOC(0, FALSE);
msg->class = C_NOTIFY;
msg->type = T_DISMANTLE_RSP;
msg->info = 0;
SendProtoMsg(cdesc, msg);
I think the underlying cause is that if there is new TCP connection that
uses a the same TCP socket descriptor
as one released with uv_poll_stop() and uv_close(), the call to
uv_poll_init() occurs before the socket closure
has propogated into the uv_loop_t Poll_Handle.
Best Regards,
Paul Romero
--
You received this message because you are subscribed to the Google Groups
"libuv" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/libuv/c3290a76-ab6b-42ad-8540-33021c6188b9n%40googlegroups.com.