diff --git a/src/http.c b/src/http.c index f6b75ff2..23ab7391 100644 --- a/src/http.c +++ b/src/http.c @@ -83,6 +83,8 @@ typedef struct _tf_http_listener_t typedef struct _tf_http_t { + bool is_shutting_down; + tf_http_listener_t** listeners; int listeners_count; @@ -208,6 +210,12 @@ static void _http_connection_destroy(tf_http_connection_t* connection, const cha connection->fragment = NULL; } tf_free(connection); + + if (http->is_shutting_down && + http->connections_count == 0) + { + tf_http_destroy(http); + } } } @@ -687,48 +695,54 @@ static void _http_free_listener_on_close(uv_handle_t* handle) void tf_http_destroy(tf_http_t* http) { - for (int i = 0; i < http->listeners_count; i++) - { - tf_http_listener_t* listener = http->listeners[i]; - if (listener->cleanup) - { - listener->cleanup(listener->user_data); - } - uv_close((uv_handle_t*)&listener->tcp, _http_free_listener_on_close); - } - tf_free(http->listeners); - http->listeners = NULL; - http->listeners_count = 0; - - for (int i = 0; i < http->handlers_count; i++) - { - if (http->handlers[i].pattern) - { - tf_free((void*)http->handlers[i].pattern); - http->handlers[i].pattern = NULL; - } - if (http->handlers[i].cleanup) - { - http->handlers[i].cleanup(http->handlers[i].user_data); - } - } - tf_free(http->handlers); - http->handlers_count = 0; + http->is_shutting_down = true; for (int i = 0; i < http->connections_count; i++) { _http_connection_destroy(http->connections[i], "tf_http_destroy"); } - tf_free(http->connections); - http->connections_count = 0; - if (http->user_data_cleanup) + if (http->connections_count == 0) { - http->user_data_cleanup(http->user_data); - http->user_data = NULL; - } + tf_free(http->connections); + http->connections = NULL; - tf_free(http); + for (int i = 0; i < http->listeners_count; i++) + { + tf_http_listener_t* listener = http->listeners[i]; + if (listener->cleanup) + { + listener->cleanup(listener->user_data); + } + uv_close((uv_handle_t*)&listener->tcp, _http_free_listener_on_close); + } + tf_free(http->listeners); + http->listeners = NULL; + http->listeners_count = 0; + + for (int i = 0; i < http->handlers_count; i++) + { + if (http->handlers[i].pattern) + { + tf_free((void*)http->handlers[i].pattern); + http->handlers[i].pattern = NULL; + } + if (http->handlers[i].cleanup) + { + http->handlers[i].cleanup(http->handlers[i].user_data); + } + } + tf_free(http->handlers); + http->handlers_count = 0; + + if (http->user_data_cleanup) + { + http->user_data_cleanup(http->user_data); + http->user_data = NULL; + } + + tf_free(http); + } } const char* tf_http_status_text(int status)