write usage of the libuv tcp client

1,115 views
Skip to first unread message

Claudio Bisegni

unread,
Jul 2, 2014, 5:40:30 AM7/2/14
to li...@googlegroups.com
Hi i have some problem to well understand the libuv functionality on when deallocate the handler and stream.

i have a cpp class that have a one uv_tcp_t instance for the client. When i need to send data to one server i do the following step:

i use a struct RequestInfo * ri to keep the reference to the tcp_connection for close it.

1) allocate the connection with ri->tcp_connection = (uv_connect_t*)malloc(sizeof(uv_connect_t));
2) call the uv_tcp_connect(ri->tcp_connection, &client, (const struct sockaddr*)&req_addr, TCPUVClient::on_connect); where the 'client' is the unique instance of uv_tcp_t;
3) below my on connect:

void TCPUVClient::on_connect(uv_connect_t *connection, int status) {

RequestInfo *ri = static_cast<RequestInfo*>(connection->data);

if (status) {

TCPUVClientLERR << "error on_connect" << status;

uv_close((uv_handle_t*)connection,TCPUVClient::on_close);

DEALLOCATE_REQUEST_INFO(ri)

return;

}


//get the data to send

ri->serializationBuffer = ri->messageInfo->message->getBSONData();

//initialize uv buffer

uv_buf_t buf = uv_buf_init((char*)ri->serializationBuffer->getBufferPtr(), (unsigned int)ri->serializationBuffer->getBufferLen());

//connect data to stream handler

connection->handle->data = connection->data;

uv_write_t request;

uv_write(&request, connection->handle, &buf, 1, TCPUVClient::on_write_end);

}


4) after the data is sent i need to read the ack answer with:

void TCPUVClient::on_ack_read(uv_stream_t *stream, ssize_t nread, const uv_buf_t* buf) {

//delete the forward info class

RequestInfo *ri = static_cast<RequestInfo*>(stream->data);

stream->data = NULL;

if (nread>0) {

auto_ptr<chaos::common::data::CDataWrapper> ack_result(new chaos::common::data::CDataWrapper(buf->base));

LDBG_ << "TCPUVClient::on_ack_read message result------------------------------";

LDBG_ << ack_result->getJSONString();

LDBG_ << "TCPUVClient::on_ack_read message result------------------------------";

//uv_close((uv_handle_t*) server, TCPUVClient::on_close);

return;

}

uv_close((uv_handle_t*)stream, TCPUVClient::on_close);

free(buf->base);

DEALLOCATE_REQUEST_INFO(ri)

}


void TCPUVClient::on_write_end(uv_write_t *req, int status) {

RequestInfo *ri = static_cast<RequestInfo*>(req->data);

if (status) {

TCPUVClientLERR << "error on_write_end ->" << status;

uv_close((uv_handle_t*)ri->tcp_connection,TCPUVClient::on_close);

DEALLOCATE_REQUEST_INFO(ri)

return;

}

uv_read_start(req->handle, TCPUVClient::alloc_buffer, TCPUVClient::on_ack_read);

} 


my question is when i need to call uv_close for:

uv_write_t *req contained in on_write_end

uv_stream_t *stream contained in on_ack_read

uv_connect_t *connection contained in on_connection


the client work but i don't now if i forgot to free memory.


thanks in advanced for all group. And there is a good example on how work well with libuv?

Fedor Indutny

unread,
Jul 2, 2014, 5:47:02 AM7/2/14
to li...@googlegroups.com
Hello!

You don't need to `uv_close()` any request, just release the memory in their callbacks.
This applies to `uv_write_t`, `uv_connect_t` and everything that doesn't inherit from handle.

`uv_close()` is closing underlying socket, so please call it only when you are done with the socket and
do not want to receive or send anything on it.

Cheers,
Fedor.


--
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 libuv+un...@googlegroups.com.
To post to this group, send email to li...@googlegroups.com.
Visit this group at http://groups.google.com/group/libuv.
For more options, visit https://groups.google.com/d/optout.

Claudio Bisegni

unread,
Jul 4, 2014, 10:34:28 AM7/4/14
to li...@googlegroups.com, fe...@indutny.com
thank for answer, so if i have mean,
i can call free on on_connect(uv_connect_t *connection, int status) for the connection parameter and call onlcose only for the real socket..
right?

Fedor Indutny

unread,
Jul 4, 2014, 10:35:54 AM7/4/14
to li...@googlegroups.com
Yes.

Iñaki Baz Castillo

unread,
Jul 4, 2014, 10:37:49 AM7/4/14
to li...@googlegroups.com, fe...@indutny.com
2014-07-04 16:34 GMT+02:00 Claudio Bisegni <cbis...@gmail.com>:
> i can call free on on_connect(uv_connect_t *connection, int status) for the
> connection parameter and call onlcose only for the real socket..
> right?

Mmmm, really not. Call uv_close(uv_handle) and free it on the on_close callback.


--
Iñaki Baz Castillo
<i...@aliax.net>

Claudio Bisegni

unread,
Jul 4, 2014, 10:42:43 AM7/4/14
to li...@googlegroups.com, fe...@indutny.com
to be more clear:

void TCPUVServer::on_write_end(uv_write_t *req, int status) {

TCPUVServerLDBG << "on_write_end ";

//delete the sent data

chaos::common::data::SerializationBuffer *ser = static_cast<chaos::common::data::SerializationBuffer*>(req->data);

if(ser) delete(ser);

if (status) {

TCPUVServerLERR << "error on_write_end:" << status;

}

uv_close((uv_handle_t*)req->handle, TCPUVServer::on_close);

free(req);

}


on_write_end is the last step on my protocollo (create a server-> accept more socket for every connection i read and write the ack and the i close the connection).
is on_write_end method well managed the on_close method do the free action.

Claudio Bisegni

unread,
Jul 4, 2014, 10:44:50 AM7/4/14
to li...@googlegroups.com, fe...@indutny.com
for clear the uv_write_t (that has the tcp socket handle into it i need to call 

on_write_end(uv_write_t *req, int status) {

...

uv_close((uv_handle_t*)req, TCPUVServer::on_close);

uv_close((uv_handle_t*)handle->handle, TCPUVServer::on_close);

...
}

void TCPUVServer::on_close(uv_handle_t* handle) {

TCPUVServerLDBG << "on_close ";

free(handle);

}


?

Fedor Indutny

unread,
Jul 4, 2014, 10:47:00 AM7/4/14
to li...@googlegroups.com
No, uv_write_t is a request, you should not call `uv_close()` on it.


--

Claudio Bisegni

unread,
Jul 4, 2014, 10:52:22 AM7/4/14
to li...@googlegroups.com, fe...@indutny.com
ok for the request but for connection? Castillo sai different things

Claudio Bisegni

unread,
Jul 4, 2014, 10:57:07 AM7/4/14
to li...@googlegroups.com, fe...@indutny.com
Another question,
i create my loop and, when i need to send something so server i allocate che client. For this reason i have a thread method with:

while(run) {

uv_run(loop, UV_RUN_NOWAIT);

usleep(100);

}


is the right way to use this run mode?

Iñaki Baz Castillo

unread,
Jul 4, 2014, 10:58:45 AM7/4/14
to li...@googlegroups.com, fe...@indutny.com
2014-07-04 16:52 GMT+02:00 Claudio Bisegni <cbis...@gmail.com>:
> ok for the request but for connection? Castillo sai different things


No, I didn't.

Iñaki Baz Castillo

unread,
Jul 4, 2014, 11:00:35 AM7/4/14
to li...@googlegroups.com, fe...@indutny.com
2014-07-04 16:42 GMT+02:00 Claudio Bisegni <cbis...@gmail.com>:
> void TCPUVServer::on_write_end(uv_write_t *req, int status) {
>
> TCPUVServerLDBG << "on_write_end ";
>
> //delete the sent data
>
> chaos::common::data::SerializationBuffer *ser =
> static_cast<chaos::common::data::SerializationBuffer*>(req->data);
>
> if(ser) delete(ser);
>
> if (status) {
>
> TCPUVServerLERR << "error on_write_end:" << status;
>
> }
>
> uv_close((uv_handle_t*)req->handle, TCPUVServer::on_close);
>
> free(req);
>
> }
>
>
> on_write_end is the last step on my protocollo (create a server-> accept
> more socket for every connection i read and write the ack and the i close
> the connection).

> is on_write_end method well managed the on_close method do the free action.

Indeed you can call uv_close on any handle callback.

Saúl Ibarra Corretgé

unread,
Jul 4, 2014, 11:01:12 AM7/4/14
to li...@googlegroups.com
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
No. Also, what do you mean by "a thread method"? Note than uv_run is
not thread-safe.


- --
Saúl Ibarra Corretgé
bettercallsaghul.com

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1
Comment: Using GnuPG with Icedove - http://www.enigmail.net/

iQIcBAEBAgAGBQJTtsF0AAoJEEEOVVOum8BZAWYQAIuMz0416yCHgU9bhr45kCC4
m8i96X/n/sSDH3oOH4D+V0HZHmDYvH7moRtJoBE1Gr9ibj526PXGStWM+wCQXtCA
kLy1iMVH7Ecwquz0lRHqlVd7HSD+UEsW5uDohLN3MlZD/kVWRhP/gEqgFSd0F4N4
NXW4+lv5fY36jTCTZZDO3RYiFlOv1++eL3FVrsgX6dDF/a4M0PeptmCjdfZfLPPQ
DNV++S/pqnL4KEAPRv3EhA35AD0gd74D9z2d7BCFW/D1Ogl3uvk2l8FqA7UKFcA+
WoqqrVz3jtxUo/3qSFnIQnc6Do3lxYzcL/YgD5G5gG7Ck7AIdidkCp8TjZLpmGfx
tGn0+oCf4WmNgRXmediBO7txV5P86ULZWBnik3OBgRlt0FTBcJADIlDoOO3A+LUt
HigSK8gHlXwtLQ+Z76azJ63HufRei3VTw082qJVQBzU7cuX8R7vZtOR722qG6z40
2sbLdcgldXC1FkbH2bPXHQNk1xHAPLGIz32wbZUvYxWlvh/lRuTjPNzRVK4FqiDP
IzdCEB4plsQ36TB9S9IWzwuOqkmOBpgeDgQ9kJTOKoVr75MwvRhHgc2A34GpgmTZ
Ot/BhJcOrhuxNhv0aC+HacyntF4tAtiOGzK0U1mFIdAEar4XTHoKqcI5tVTTGmVr
NuDM6puec2dVS0FHGvCn
=MNeS
-----END PGP SIGNATURE-----

Iñaki Baz Castillo

unread,
Jul 4, 2014, 11:01:34 AM7/4/14
to li...@googlegroups.com, fe...@indutny.com
2014-07-04 16:44 GMT+02:00 Claudio Bisegni <cbis...@gmail.com>:
> uv_close((uv_handle_t*)req, TCPUVServer::on_close);

No, uv_close is just for handles, not for requests. Just free the
request (if you allocated it with malloc).

Claudio Bisegni

unread,
Jul 4, 2014, 4:10:01 PM7/4/14
to li...@googlegroups.com
i have incoported lib into my app. The application has may thread and many service. LibUV is used to realise the RPC service and the start of this service is done within the main sequence that start several service. So the uv_run can't block the flow of service initialization. To achieve this i put the uv_run within a thread method
and when i need i call uv_tcp_connect with the loop to start the client.

Claudio Bisegni

unread,
Jul 4, 2014, 4:27:45 PM7/4/14
to li...@googlegroups.com
summarizing, i need to have a single class that own the loop and the async method, but other thread can send data to more server.
So this class need to create the tcp socket for endpoint server and send data. Now i do this using un loop launched into another thread with uv_run(loop, etc...)
the method that call the uv_tcp_connect live in another thread. 

I need to have a different loop with a different connection?

thanks for the help
Reply all
Reply to author
Forward
0 new messages