Reputation: 96
I've read the tcp-echo-server.c example from libuv, now I'm writing a small multi-thread tcp server based on that.
I used the uv_default_loop
in the main thread to accept connections, and put new connection into a list.
// main thread
uv_ip4_addr("0.0.0.0", DEFAULT_PORT, &addr);
uv_tcp_bind(&server, (const struct sockaddr*)&addr, 0);
int r = uv_listen((uv_stream_t*) &server, DEFAULT_BACKLOG, OnConnectionCallback);
if (r)
{
ERROR("Listen error %s", uv_strerror(r));
return;
}
uv_run(loop, UV_RUN_DEFAULT);
and in the second thread, I broadcast a message to all connections I've got.
// second thread
write_req_t *req = (write_req_t*) malloc(sizeof(write_req_t));
req->buf = uv_buf_init((char *)buffer->data(), buffer->size());
int r = uv_write((uv_write_t*) req, (uv_stream_t *)this->uv, &req->buf, 1, write_callback);
if (r)
{
ERROR("uv_write error: %s", uv_strerror(ret));
}
accepting connection works, reading from client works, but the writing part didn't work. no error code reported, but it's callback never got triggered.
I went through the doc, unable to find any clue yet. What did I miss?
by the way, I'm using std::thread
, not the thread api from libuv.
Upvotes: 2
Views: 1622
Reputation: 411
libuv is not thread safe thus you need to always access the loop from the same thread where it is running. If you want to push something from another thread you need to use uv_async_send
function as follows.
uv_loop_t loop;
uv_async_t async;
...
uv_async_init(loop, &async, [](uv_async_t* handle) {
...
// call uv_write or any uv functions
});
uv_async_send(async);
Upvotes: 2