diff --git a/examples/client.c b/examples/client.c index dd101f2..5c885e5 100644 --- a/examples/client.c +++ b/examples/client.c @@ -69,9 +69,9 @@ main (int argc, char **argv) { uv_loop_init(&loop); - udx_init(&loop, &udx); + udx_init(&loop, &udx, NULL); - udx_socket_init(&udx, &sock); + udx_socket_init(&udx, &sock, NULL); struct sockaddr_in addr; uv_ip4_addr("0.0.0.0", 18082, &addr); diff --git a/examples/server.c b/examples/server.c index 1b7aff4..7969166 100644 --- a/examples/server.c +++ b/examples/server.c @@ -115,9 +115,9 @@ main (int argc, char **argv) { chunk.len = 16384; chunk.base = calloc(1, chunk.len); - udx_init(&loop, &udx); + udx_init(&loop, &udx, NULL); - udx_socket_init(&udx, &sock); + udx_socket_init(&udx, &sock, NULL); struct sockaddr_in addr; uv_ip4_addr("0.0.0.0", 18081, &addr); diff --git a/examples/udxperf.c b/examples/udxperf.c index 5ff6811..2b5942b 100644 --- a/examples/udxperf.c +++ b/examples/udxperf.c @@ -599,8 +599,8 @@ main (int argc, char **argv) { } uv_loop_init(&loop); - udx_init(&loop, &udx); - udx_socket_init(&udx, &sock); + udx_init(&loop, &udx, NULL); + udx_socket_init(&udx, &sock, NULL); if (is_server) { server(); diff --git a/include/udx.h b/include/udx.h index 0948fec..2c860ea 100644 --- a/include/udx.h +++ b/include/udx.h @@ -108,6 +108,8 @@ struct udx_s { uv_loop_t *loop; int refs; + bool teardown; + udx_idle_cb on_idle; udx_socket_t *sockets; @@ -405,13 +407,16 @@ struct udx_interface_event_s { }; int -udx_init (uv_loop_t *loop, udx_t *udx); +udx_init (uv_loop_t *loop, udx_t *udx, udx_idle_cb on_idle); + +int +udx_is_idle (udx_t *udx); void -udx_idle (udx_t *udx, udx_idle_cb cb); +udx_teardown (udx_t *udx); int -udx_socket_init (udx_t *udx, udx_socket_t *socket); +udx_socket_init (udx_t *udx, udx_socket_t *socket, udx_socket_close_cb cb); int udx_socket_get_send_buffer_size (udx_socket_t *socket, int *value); @@ -462,7 +467,7 @@ int udx_socket_recv_stop (udx_socket_t *socket); int -udx_socket_close (udx_socket_t *socket, udx_socket_close_cb cb); +udx_socket_close (udx_socket_t *socket); // only exposed here as a convenience / debug tool - the udx instance uses this automatically int @@ -532,7 +537,7 @@ int udx_lookup (udx_t *udx, udx_lookup_t *req, const char *host, unsigned int flags, udx_lookup_cb cb); int -udx_interface_event_init (udx_t *udx, udx_interface_event_t *handle); +udx_interface_event_init (udx_t *udx, udx_interface_event_t *handle, udx_interface_event_close_cb cb); int udx_interface_event_start (udx_interface_event_t *handle, udx_interface_event_cb cb, uint64_t frequency); @@ -541,7 +546,7 @@ int udx_interface_event_stop (udx_interface_event_t *handle); int -udx_interface_event_close (udx_interface_event_t *handle, udx_interface_event_close_cb cb); +udx_interface_event_close (udx_interface_event_t *handle); #ifdef __cplusplus } diff --git a/src/udx.c b/src/udx.c index c1ed140..04ee53a 100644 --- a/src/udx.c +++ b/src/udx.c @@ -644,6 +644,13 @@ close_stream (udx_stream_t *stream, int err) { uv_close((uv_handle_t *) &stream->tlp_timer, finalize_maybe); uv_close((uv_handle_t *) &stream->zwp_timer, finalize_maybe); + if (udx->teardown && udx->streams == NULL) { + udx_socket_t *socket; + udx__link_foreach(udx->sockets, socket) { + udx_socket_close(socket); + } + } + return 1; } @@ -1938,9 +1945,10 @@ on_uv_poll (uv_poll_t *handle, int status, int events) { } int -udx_init (uv_loop_t *loop, udx_t *udx) { +udx_init (uv_loop_t *loop, udx_t *udx, udx_idle_cb on_idle) { udx->refs = 0; - udx->on_idle = NULL; + udx->teardown = false; + udx->on_idle = on_idle; udx->sockets = NULL; udx->streams = NULL; @@ -1963,11 +1971,39 @@ udx_idle (udx_t *udx, udx_idle_cb cb) { } int -udx_socket_init (udx_t *udx, udx_socket_t *socket) { +udx_is_idle (udx_t *udx) { + return udx->refs == 0; +} + +void +udx_teardown (udx_t *udx) { + udx->teardown = true; + + if (udx->streams == NULL) { + udx_socket_t *socket; + udx__link_foreach(udx->sockets, socket) { + udx_socket_close(socket); + } + } + + udx_stream_t *stream; + udx__link_foreach(udx->streams, stream) { + udx_stream_destroy(stream); + } + + udx_interface_event_t *listener; + udx__link_foreach(udx->listeners, listener) { + udx_interface_event_close(listener); + } +} + +int +udx_socket_init (udx_t *udx, udx_socket_t *socket, udx_socket_close_cb cb) { udx->refs++; udx__link_add(udx->sockets, socket); + socket->on_close = cb; socket->family = 0; socket->status = 0; socket->events = 0; @@ -2190,13 +2226,11 @@ udx_socket_recv_stop (udx_socket_t *socket) { } int -udx_socket_close (udx_socket_t *socket, udx_socket_close_cb cb) { +udx_socket_close (udx_socket_t *socket) { if (check_for_streams(socket)) return UV_EBUSY; socket->status |= UDX_SOCKET_CLOSED; - socket->on_close = cb; - while (socket->send_queue.len > 0) { udx_packet_t *pkt = udx__queue_data(udx__queue_shift(&socket->send_queue), udx_packet_t, queue); assert(pkt != NULL); @@ -2803,10 +2837,11 @@ on_interface_event_close (uv_handle_t *handle) { } int -udx_interface_event_init (udx_t *udx, udx_interface_event_t *handle) { +udx_interface_event_init (udx_t *udx, udx_interface_event_t *handle, udx_interface_event_close_cb cb) { handle->udx = udx; handle->loop = udx->loop; handle->sorted = false; + handle->on_close = cb; int err = uv_interface_addresses(&(handle->addrs), &(handle->addrs_len)); if (err < 0) return err; @@ -2839,9 +2874,8 @@ udx_interface_event_stop (udx_interface_event_t *handle) { } int -udx_interface_event_close (udx_interface_event_t *handle, udx_interface_event_close_cb cb) { +udx_interface_event_close (udx_interface_event_t *handle) { handle->on_event = NULL; - handle->on_close = cb; uv_free_interface_addresses(handle->addrs, handle->addrs_len); diff --git a/test/lookup-invalid.c b/test/lookup-invalid.c index 22d3ba4..2d8a80e 100644 --- a/test/lookup-invalid.c +++ b/test/lookup-invalid.c @@ -22,7 +22,7 @@ main () { int e; uv_loop_init(&loop); - udx_init(&loop, &udx); + udx_init(&loop, &udx, NULL); e = udx_lookup(&udx, &req, "example.invalid.", 0, on_lookup); assert(e == 0); diff --git a/test/lookup-ipv6.c b/test/lookup-ipv6.c index 5bf7549..405fe5b 100644 --- a/test/lookup-ipv6.c +++ b/test/lookup-ipv6.c @@ -27,7 +27,7 @@ main () { int e; uv_loop_init(&loop); - udx_init(&loop, &udx); + udx_init(&loop, &udx, NULL); e = udx_lookup(&udx, &req, "localhost", UDX_LOOKUP_FAMILY_IPV6, on_lookup); assert(e == 0); diff --git a/test/lookup.c b/test/lookup.c index 7fe4fe8..c41541f 100644 --- a/test/lookup.c +++ b/test/lookup.c @@ -27,7 +27,7 @@ main () { int e; uv_loop_init(&loop); - udx_init(&loop, &udx); + udx_init(&loop, &udx, NULL); e = udx_lookup(&udx, &req, "localhost", UDX_LOOKUP_FAMILY_IPV4, on_lookup); assert(e == 0); diff --git a/test/socket-send-recv-dualstack.c b/test/socket-send-recv-dualstack.c index a1caa2c..0915097 100644 --- a/test/socket-send-recv-dualstack.c +++ b/test/socket-send-recv-dualstack.c @@ -40,13 +40,13 @@ main () { uv_loop_init(&loop); - e = udx_init(&loop, &udx); + e = udx_init(&loop, &udx, NULL); assert(e == 0); - e = udx_socket_init(&udx, &asock); + e = udx_socket_init(&udx, &asock, NULL); assert(e == 0); - e = udx_socket_init(&udx, &bsock); + e = udx_socket_init(&udx, &bsock, NULL); assert(e == 0); struct sockaddr_in baddr; diff --git a/test/socket-send-recv-ipv6.c b/test/socket-send-recv-ipv6.c index d2c9204..33294bf 100644 --- a/test/socket-send-recv-ipv6.c +++ b/test/socket-send-recv-ipv6.c @@ -40,13 +40,13 @@ main () { uv_loop_init(&loop); - e = udx_init(&loop, &udx); + e = udx_init(&loop, &udx, NULL); assert(e == 0); - e = udx_socket_init(&udx, &asock); + e = udx_socket_init(&udx, &asock, NULL); assert(e == 0); - e = udx_socket_init(&udx, &bsock); + e = udx_socket_init(&udx, &bsock, NULL); assert(e == 0); struct sockaddr_in6 baddr; diff --git a/test/socket-send-recv-multicast.c b/test/socket-send-recv-multicast.c index 8945367..2c5b45e 100644 --- a/test/socket-send-recv-multicast.c +++ b/test/socket-send-recv-multicast.c @@ -46,13 +46,13 @@ main () { uv_loop_init(&loop); - e = udx_init(&loop, &udx); + e = udx_init(&loop, &udx, NULL); assert(e == 0); - e = udx_socket_init(&udx, &asock); + e = udx_socket_init(&udx, &asock, NULL); assert(e == 0); - e = udx_socket_init(&udx, &bsock); + e = udx_socket_init(&udx, &bsock, NULL); assert(e == 0); struct sockaddr_in baddr; diff --git a/test/socket-send-recv.c b/test/socket-send-recv.c index d200d21..1b7a2fc 100644 --- a/test/socket-send-recv.c +++ b/test/socket-send-recv.c @@ -40,13 +40,13 @@ main () { uv_loop_init(&loop); - e = udx_init(&loop, &udx); + e = udx_init(&loop, &udx, NULL); assert(e == 0); - e = udx_socket_init(&udx, &asock); + e = udx_socket_init(&udx, &asock, NULL); assert(e == 0); - e = udx_socket_init(&udx, &bsock); + e = udx_socket_init(&udx, &bsock, NULL); assert(e == 0); struct sockaddr_in baddr; diff --git a/test/stream-change-remote.c b/test/stream-change-remote.c index 8387d35..8c9f54f 100644 --- a/test/stream-change-remote.c +++ b/test/stream-change-remote.c @@ -91,19 +91,19 @@ main () { uv_loop_init(&loop); - e = udx_init(&loop, &udx); + e = udx_init(&loop, &udx, NULL); assert(e == 0); - e = udx_socket_init(&udx, &asock); + e = udx_socket_init(&udx, &asock, NULL); assert(e == 0); - e = udx_socket_init(&udx, &bsock); + e = udx_socket_init(&udx, &bsock, NULL); assert(e == 0); - e = udx_socket_init(&udx, &csock); + e = udx_socket_init(&udx, &csock, NULL); assert(e == 0); - e = udx_socket_init(&udx, &dsock); + e = udx_socket_init(&udx, &dsock, NULL); assert(e == 0); uv_ip4_addr("127.0.0.1", 8081, &aaddr); diff --git a/test/stream-destroy-before-connect.c b/test/stream-destroy-before-connect.c index 6e19aca..00e2907 100644 --- a/test/stream-destroy-before-connect.c +++ b/test/stream-destroy-before-connect.c @@ -10,7 +10,7 @@ main () { uv_loop_init(&loop); udx_t udx; - e = udx_init(&loop, &udx); + e = udx_init(&loop, &udx, NULL); assert(e == 0); udx_stream_t stream; diff --git a/test/stream-destroy.c b/test/stream-destroy.c index f6412a5..4f4ae46 100644 --- a/test/stream-destroy.c +++ b/test/stream-destroy.c @@ -13,7 +13,7 @@ void on_close (udx_stream_t *handle, int status) { assert(status == 0); - int e = udx_socket_close(&sock, NULL); + int e = udx_socket_close(&sock); assert(e == 0); @@ -26,10 +26,10 @@ main () { uv_loop_init(&loop); - e = udx_init(&loop, &udx); + e = udx_init(&loop, &udx, NULL); assert(e == 0); - e = udx_socket_init(&udx, &sock); + e = udx_socket_init(&udx, &sock, NULL); assert(e == 0); struct sockaddr_in addr; diff --git a/test/stream-multiple.c b/test/stream-multiple.c index effd401..651ab9e 100644 --- a/test/stream-multiple.c +++ b/test/stream-multiple.c @@ -67,7 +67,7 @@ main () { uv_loop_init(&loop); - e = udx_init(&loop, &udx); + e = udx_init(&loop, &udx, NULL); assert(e == 0); uv_buf_t buf = uv_buf_init(malloc(NBYTES_TO_SEND), NBYTES_TO_SEND); @@ -81,7 +81,7 @@ main () { int receiver_id = NSTREAMS + i; receiver[i].read_hash = HASH_INIT; - e = udx_socket_init(&udx, &sender[i].usock); + e = udx_socket_init(&udx, &sender[i].usock, NULL); assert(e == 0); uv_ip4_addr("127.0.0.1", 8000 + i, &sender[i].addr); e = udx_socket_bind(&sender[i].usock, (struct sockaddr *) &sender[i].addr, 0); @@ -89,7 +89,7 @@ main () { sender[i].write = malloc(udx_stream_write_sizeof(1)); e = udx_stream_init(&udx, &sender[i].stream, sender_id, NULL, NULL); - udx_socket_init(&udx, &receiver[i].usock); + udx_socket_init(&udx, &receiver[i].usock, NULL); uv_ip4_addr("127.0.0.1", 8100 + i, &receiver[i].addr); e = udx_socket_bind(&receiver[i].usock, (struct sockaddr *) &receiver[i].addr, 0); assert(e == 0); diff --git a/test/stream-preconnect-same-socket.c b/test/stream-preconnect-same-socket.c index 582bc85..2acb61f 100644 --- a/test/stream-preconnect-same-socket.c +++ b/test/stream-preconnect-same-socket.c @@ -48,10 +48,10 @@ main () { uv_loop_init(&loop); - e = udx_init(&loop, &udx); + e = udx_init(&loop, &udx, NULL); assert(e == 0); - e = udx_socket_init(&udx, &sock); + e = udx_socket_init(&udx, &sock, NULL); assert(e == 0); uv_ip4_addr("127.0.0.1", 8081, &addr); diff --git a/test/stream-preconnect.c b/test/stream-preconnect.c index b9e4272..5661a69 100644 --- a/test/stream-preconnect.c +++ b/test/stream-preconnect.c @@ -49,13 +49,13 @@ main () { uv_loop_init(&loop); - e = udx_init(&loop, &udx); + e = udx_init(&loop, &udx, NULL); assert(e == 0); - e = udx_socket_init(&udx, &asock); + e = udx_socket_init(&udx, &asock, NULL); assert(e == 0); - e = udx_socket_init(&udx, &bsock); + e = udx_socket_init(&udx, &bsock, NULL); assert(e == 0); uv_ip4_addr("127.0.0.1", 8081, &aaddr); diff --git a/test/stream-relay.c b/test/stream-relay.c index 4d3fc50..f79346b 100644 --- a/test/stream-relay.c +++ b/test/stream-relay.c @@ -67,19 +67,19 @@ main () { uv_loop_init(&loop); - e = udx_init(&loop, &udx); + e = udx_init(&loop, &udx, NULL); assert(e == 0); - e = udx_socket_init(&udx, &asock); + e = udx_socket_init(&udx, &asock, NULL); assert(e == 0); - e = udx_socket_init(&udx, &bsock); + e = udx_socket_init(&udx, &bsock, NULL); assert(e == 0); - e = udx_socket_init(&udx, &csock); + e = udx_socket_init(&udx, &csock, NULL); assert(e == 0); - e = udx_socket_init(&udx, &dsock); + e = udx_socket_init(&udx, &dsock, NULL); assert(e == 0); uv_ip4_addr("127.0.0.1", 8081, &aaddr); diff --git a/test/stream-send-recv-ipv6.c b/test/stream-send-recv-ipv6.c index 87d4cc2..938f9c0 100644 --- a/test/stream-send-recv-ipv6.c +++ b/test/stream-send-recv-ipv6.c @@ -43,13 +43,13 @@ main () { uv_loop_init(&loop); - e = udx_init(&loop, &udx); + e = udx_init(&loop, &udx, NULL); assert(e == 0); - e = udx_socket_init(&udx, &asock); + e = udx_socket_init(&udx, &asock, NULL); assert(e == 0); - e = udx_socket_init(&udx, &bsock); + e = udx_socket_init(&udx, &bsock, NULL); assert(e == 0); struct sockaddr_in6 baddr; diff --git a/test/stream-send-recv.c b/test/stream-send-recv.c index 6887689..1555a8a 100644 --- a/test/stream-send-recv.c +++ b/test/stream-send-recv.c @@ -43,13 +43,13 @@ main () { uv_loop_init(&loop); - e = udx_init(&loop, &udx); + e = udx_init(&loop, &udx, NULL); assert(e == 0); - e = udx_socket_init(&udx, &asock); + e = udx_socket_init(&udx, &asock, NULL); assert(e == 0); - e = udx_socket_init(&udx, &bsock); + e = udx_socket_init(&udx, &bsock, NULL); assert(e == 0); struct sockaddr_in baddr; diff --git a/test/stream-write-read-ipv6.c b/test/stream-write-read-ipv6.c index 86ed324..68cb3fa 100644 --- a/test/stream-write-read-ipv6.c +++ b/test/stream-write-read-ipv6.c @@ -44,13 +44,13 @@ main () { uv_loop_init(&loop); - e = udx_init(&loop, &udx); + e = udx_init(&loop, &udx, NULL); assert(e == 0); - e = udx_socket_init(&udx, &asock); + e = udx_socket_init(&udx, &asock, NULL); assert(e == 0); - e = udx_socket_init(&udx, &bsock); + e = udx_socket_init(&udx, &bsock, NULL); assert(e == 0); struct sockaddr_in6 baddr; diff --git a/test/stream-write-read-multiple.c b/test/stream-write-read-multiple.c index ccbe510..4c95dca 100644 --- a/test/stream-write-read-multiple.c +++ b/test/stream-write-read-multiple.c @@ -43,13 +43,13 @@ main () { uv_loop_init(&loop); - e = udx_init(&loop, &udx); + e = udx_init(&loop, &udx, NULL); assert(e == 0); - e = udx_socket_init(&udx, &asock); + e = udx_socket_init(&udx, &asock, NULL); assert(e == 0); - e = udx_socket_init(&udx, &bsock); + e = udx_socket_init(&udx, &bsock, NULL); assert(e == 0); struct sockaddr_in baddr; diff --git a/test/stream-write-read-perf.c b/test/stream-write-read-perf.c index 02e13b2..b921d74 100644 --- a/test/stream-write-read-perf.c +++ b/test/stream-write-read-perf.c @@ -63,7 +63,7 @@ on_b_sock_close () { static void on_b_stream_close () { printf("sending stream closing\n"); - int e = udx_socket_close(&bsock, on_b_sock_close); + int e = udx_socket_close(&bsock); assert(e == 0 && "udx_socket_close (sender, 'b')"); } @@ -75,7 +75,7 @@ on_a_sock_close () { static void on_a_stream_close () { printf("receiving stream closing\n"); - int e = udx_socket_close(&asock, on_a_sock_close); + int e = udx_socket_close(&asock); assert(e == 0 && "udx_socket_close (receiver, 'a')"); } @@ -87,13 +87,13 @@ main () { uv_loop_init(&loop); - e = udx_init(&loop, &udx); + e = udx_init(&loop, &udx, NULL); assert(e == 0); - e = udx_socket_init(&udx, &asock); + e = udx_socket_init(&udx, &asock, on_a_sock_close); assert(e == 0); - e = udx_socket_init(&udx, &bsock); + e = udx_socket_init(&udx, &bsock, on_b_sock_close); assert(e == 0); struct sockaddr_in baddr; diff --git a/test/stream-write-read-receive-window.c b/test/stream-write-read-receive-window.c index 5889139..6e2711f 100644 --- a/test/stream-write-read-receive-window.c +++ b/test/stream-write-read-receive-window.c @@ -49,8 +49,8 @@ void on_finalize (udx_stream_t *stream) { nfinalize++; if (nfinalize == 2) { - udx_socket_close(&send_sock, on_socket_close); - udx_socket_close(&recv_sock, on_socket_close); + udx_socket_close(&send_sock); + udx_socket_close(&recv_sock); } } @@ -90,13 +90,13 @@ main () { uv_loop_init(&loop); - e = udx_init(&loop, &udx); + e = udx_init(&loop, &udx, NULL); assert(e == 0); - e = udx_socket_init(&udx, &recv_sock); + e = udx_socket_init(&udx, &recv_sock, on_socket_close); assert(e == 0); - e = udx_socket_init(&udx, &send_sock); + e = udx_socket_init(&udx, &send_sock, on_socket_close); assert(e == 0); struct sockaddr_in send_addr; diff --git a/test/stream-write-read.c b/test/stream-write-read.c index 1bbdc5d..27ac2de 100644 --- a/test/stream-write-read.c +++ b/test/stream-write-read.c @@ -29,8 +29,8 @@ on_close (udx_stream_t *s, int status) { nclosed++; if (nclosed == 2) { - udx_socket_close(&asock, NULL); - udx_socket_close(&bsock, NULL); + udx_socket_close(&asock); + udx_socket_close(&bsock); } } @@ -65,13 +65,13 @@ main () { uv_loop_init(&loop); - e = udx_init(&loop, &udx); + e = udx_init(&loop, &udx, NULL); assert(e == 0); - e = udx_socket_init(&udx, &asock); + e = udx_socket_init(&udx, &asock, NULL); assert(e == 0); - e = udx_socket_init(&udx, &bsock); + e = udx_socket_init(&udx, &bsock, NULL); assert(e == 0); struct sockaddr_in baddr;