diff --git a/uvserver.c b/uvserver.c index 4b342d0..747f7e7 100644 --- a/uvserver.c +++ b/uvserver.c @@ -5,6 +5,8 @@ #include +static uv_tcp_t serversock; +static uv_timer_t stats; static int connection_count = 0; static void on_timer(uv_timer_t *timer) { @@ -22,16 +24,31 @@ static void on_write_complete(uv_write_t *req, int status) { free(req); } +static void on_timer_closed(uv_handle_t *timer) { + printf("Exiting after timer shutdown.\n"); + uv_stop(timer->loop); +} + +static void on_serversock_closed(uv_handle_t *serversock) { + printf("Shutting down statistics timer after server socket shutdown.\n"); + uv_timer_stop(&stats); + uv_close((uv_handle_t *) &stats, on_timer_closed); +} + +static void on_conn_closed(uv_handle_t *conn) { + connection_count--; + if (connection_count == 0) { + printf("Shutting down server socket on zero connection count.\n"); + uv_close((uv_handle_t *) &serversock, on_serversock_closed); + } + free(conn); +} + static void on_input(uv_stream_t *conn, ssize_t nread, uv_buf_t const *buf) { if (nread < 0) { /* here we could check uv_last_error(conn->loop).code to see whether it's UV_EOF or not */ /* but we don't care; just close, and be done */ - connection_count--; - if (connection_count == 0) { - printf("Exiting on zero connection count.\n"); - uv_stop(conn->loop); - } - uv_close((uv_handle_t *) conn, NULL); + uv_close((uv_handle_t *) conn, on_conn_closed); if (buf->base != NULL) { free(buf->base); } @@ -65,9 +82,7 @@ static void on_connection(uv_stream_t *serversock, int status) { static int const PORTNUMBER = 5999; int main(int argc, char const *argv[]) { - uv_loop_t *uv = uv_default_loop(); - uv_tcp_t serversock; - uv_timer_t stats; + uv_loop_t uv; struct sockaddr_in bind_addr; printf("uvserver; libuv version %s\n", uv_version_string()); @@ -76,17 +91,19 @@ int main(int argc, char const *argv[]) { return 0; } + uv_loop_init(&uv); + printf("Accepting connections on port %d.\n", PORTNUMBER); - uv_tcp_init(uv, &serversock); + uv_tcp_init(&uv, &serversock); uv_ip4_addr("0.0.0.0", PORTNUMBER, &bind_addr); uv_tcp_bind(&serversock, (struct sockaddr const *) &bind_addr, 0); uv_listen((uv_stream_t *) &serversock, 4, on_connection); - uv_timer_init(uv, &stats); + uv_timer_init(&uv, &stats); uv_timer_start(&stats, on_timer, 2000, 2000); - uv_run(uv, UV_RUN_DEFAULT); + uv_run(&uv, UV_RUN_DEFAULT); - uv_loop_delete(uv); + uv_loop_close(&uv); return 0; }