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.

Reply via email to