Hi,

On 02/12/15 02:16, Brian Nichols wrote:
I have a tcp connection with a timer.  I want to close or timeout the
connection and safely release resources.  There will be many connections
running concurrently.

1) Does uv_close() need to be called on the timer in addition to the tcp
connection?


Yes. All handles need to be uv_close()-ed before you can free the memory associated with them.

2) Is the code below correct?


Other than some missing error checking looks ok to me.

3) Is there a more efficient or elegant way to safely free a tcp
connection with a timer?


A couple of quick notes:

You don't need to stop a timer if you are going to close it right after, uv_close will take care of that.

You can use container_of in order to avoid storing pointers in the data fields. Have a look at how we do it inside libuv.

The closing mechanism could be simplified by using a counter: you know 2 handles need to be closed, so pass the same close callback to both. In it, decrease the counter (which you initialize to 2), when it reaches 0 you can free the structure.


Cheers,


struct my_connection {
uv_tcp_t socket;
uv_timer_t timer;
uv_connect_t connect;
bool timer_closed;
bool socket_closed;
} my_connection;

my_connection* open_connection(uv_loop_t* loop, struct sockaddr* addr) {
my_connection* conn = malloc(sizeof(my_connection));
conn->timer.data = conn;
conn->socket.data = conn;
conn->timer_closed = false;
conn->socket_closed = false;

uv_timer_init(loop, &conn->timer);
uv_timer_start(&conn->timer, timeout_cb, 1000, 0);
uv_tcp_init(loop, &conn->socket);
uv_tcp_connect(&conn->connect, &conn->socket, addr, connect_cb);
return conn;
}

void connect_cb(uv_connect_t* connect, int status) {
// Start writing to socket if connected.
// When finished, call close_connection().
}

void close_connection(my_connection* conn) {
uv_timer_stop(&conn->timer);

// Does timer need to be closed after stopping?
uv_close((uv_handle_t*)&conn->timer, timer_closed_cb);
uv_close((uv_handle_t*)&conn->socket, socket_closed_cb);
}

void timeout_cb(uv_timer_t* timer) {
my_connection* conn = timer->data;

// Does timer need to be closed on timeout?
uv_close((uv_handle_t*)&conn->timer, timer_closed_cb);
uv_close((uv_handle_t*)&conn->socket, socket_closed_cb);
}

void
timer_closed_cb(uv_handle_t* handle) {
my_connection* conn = handle->data;
conn->timer_closed = true;

if (conn->socket_closed)
free(conn);
}

void
socket_closed_cb(uv_handle_t* handle) {
my_connection* conn = handle->data;
conn->socket_closed = true;

if (conn->timer_closed)
free(conn);
}

--
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]
<mailto:[email protected]>.
To post to this group, send email to [email protected]
<mailto:[email protected]>.
Visit this group at http://groups.google.com/group/libuv.
For more options, visit https://groups.google.com/d/optout.


--
Saúl Ibarra Corretgé
http://bettercallsaghul.com

--
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 post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/libuv.
For more options, visit https://groups.google.com/d/optout.

Reply via email to