Hi,
I cannot figure out how to achieve the following: to add a new uv_tcp_t to already active uv loop which is presently blocked on IO.
In detail:
My uv event loop is invoked as UV_RUN_DEFAULT. This is managing the IO for a single TCP connection which was actively established as follows:
uv_connect_t connect_req;
struct sockaddr_in addr;
uv_ip4_addr("127.0.0.1", 40001, &addr);
uv_tcp_init(uv_default_loop(), &tcp_handle_1);
uv_tcp_connect(&connect_req,
&tcp_handle_1,
(const struct sockaddr*) &addr,
connect_cb);
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
In the connect_cb() the read is enabled:
static void connect_cb(uv_connect_t* req, int status)
{
uv_read_start(req->handle, alloc_buffer, on_read);
}
Nothing surprising so far, and all works ; this is a single actively established socket which can read from other side.
Next, slightly later, and in a separate thread, I wish to create a new uv_tcp_t handle and add that to the loop, so I do the same (just changing the handle variable):
uv_connect_t connect_req;
struct sockaddr_in addr;
uv_ip4_addr("127.0.0.1", 40002, &addr);
uv_tcp_init(uv_default_loop(), &tcp_handle_2);
uv_tcp_connect(&connect_req,
&tcp_handle_2,
(const struct sockaddr*) &addr,
connect_cb);
Now the problem I encounter is that while I do see a connection is made to
127.0.0.1:40002, this second stream (tcp_handle_2) does not read from the socket. In fact it will read, but only after some bytes have arrived on the first connection.
I think the problem is that the uv event loop is blocked in the IO; so when tcp_handle_2 is added, the uv loop does not immediately call the connect_cb() to set up the stream reading. The uv loop remains blocked until bytes appears on tcp_handle_1, at which point the connect_cb() for tcp_handle_2 is called and then reads can take place.
So what's the best approach to resolve this? I would like to have a single uv event loop to manage many actively established connections, but I have not found a way to interrupt an io-blocked uv loop so that it can deliver the callbacks associated with setting up a new connection. One possible approach would be to use an idler, however if I try that, I see CPU use rise to 100%. Another approach might be to use something like socketpair to manually interrupt the uv loop; but I've not yet found that in libuv.
Help appreciated. Thanks,
Darren