From 685754895b5b9bbbef9433ef12f0a9ca85faae80 Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Tue, 13 Feb 2024 23:07:36 +0000 Subject: [PATCH] Have we achieved clean shutdown? git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4841 ed5197a5-7fde-0310-b194-c3ffbd925b24 --- src/http.c | 39 ++++++++++++++++++++++------------- src/httpd.js.c | 1 + src/ssb.c | 52 +++++++++++++++++++++++++++++------------------ src/task.c | 28 +++++++++++++++++-------- src/taskstub.js.c | 38 ++++++---------------------------- src/taskstub.js.h | 1 - 6 files changed, 84 insertions(+), 75 deletions(-) diff --git a/src/http.c b/src/http.c index 23ab7391..e91dbb8e 100644 --- a/src/http.c +++ b/src/http.c @@ -702,6 +702,31 @@ void tf_http_destroy(tf_http_t* http) _http_connection_destroy(http->connections[i], "tf_http_destroy"); } + 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); + listener->cleanup = NULL; + } + } + + for (int i = 0; i < http->handlers_count; i++) + { + if (http->handlers[i].cleanup) + { + http->handlers[i].cleanup(http->handlers[i].user_data); + http->handlers[i].cleanup = NULL; + } + } + + if (http->user_data_cleanup) + { + http->user_data_cleanup(http->user_data); + http->user_data = NULL; + } + if (http->connections_count == 0) { tf_free(http->connections); @@ -710,10 +735,6 @@ 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); @@ -727,20 +748,10 @@ void tf_http_destroy(tf_http_t* http) 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); } } diff --git a/src/httpd.js.c b/src/httpd.js.c index 4dc87dfd..c3e41dba 100644 --- a/src/httpd.js.c +++ b/src/httpd.js.c @@ -2,6 +2,7 @@ #include "file.js.h" #include "http.h" +#include "log.h" #include "mem.h" #include "task.h" #include "tlscontext.js.h" diff --git a/src/ssb.c b/src/ssb.c index ce4da015..677b93fa 100644 --- a/src/ssb.c +++ b/src/ssb.c @@ -2376,8 +2376,12 @@ void tf_ssb_destroy(tf_ssb_t* ssb) { tf_printf("tf_ssb_destroy\n"); ssb->shutting_down = true; - tf_ssb_connections_destroy(ssb->connections_tracker); - ssb->connections_tracker = NULL; + + if (ssb->connections_tracker) + { + tf_ssb_connections_destroy(ssb->connections_tracker); + ssb->connections_tracker = NULL; + } if (ssb->broadcast_listener.data && !uv_is_closing((uv_handle_t*)&ssb->broadcast_listener)) { @@ -2489,19 +2493,11 @@ void tf_ssb_destroy(tf_ssb_t* ssb) tf_free(node); } - tf_printf("rpc=%p conn_changed=%p mess_add=%p blob_want_add=%p broadcast_change=%p\n", - ssb->rpc, - ssb->connections_changed, - ssb->message_added, - ssb->blob_want_added, - ssb->broadcasts_changed); - tf_printf("Closing connections.\n"); tf_ssb_connection_t* connection = ssb->connections; while (connection) { tf_ssb_connection_t* next = connection->next; - tf_printf("close %p\n", connection); tf_ssb_connection_close(connection); connection = next; } @@ -2515,13 +2511,18 @@ void tf_ssb_destroy(tf_ssb_t* ssb) tf_printf("uv_loop_close: %s\n", uv_strerror(r)); } } - tf_printf("loop closed\n"); + tf_printf("uv loop closed.\n"); if (ssb->own_context) { JS_FreeContext(ssb->context); JS_FreeRuntime(ssb->runtime); + ssb->own_context = false; + } + if (ssb->db_writer) + { + sqlite3_close(ssb->db_writer); + ssb->db_writer = NULL; } - sqlite3_close(ssb->db_writer); while (ssb->broadcasts) { tf_ssb_broadcast_t* broadcast = ssb->broadcasts; @@ -2540,17 +2541,28 @@ void tf_ssb_destroy(tf_ssb_t* ssb) { sqlite3_close(ssb->db_readers[i]); } - tf_free(ssb->db_readers); - tf_printf("destroying mutexes\n"); - uv_mutex_destroy(&ssb->db_readers_lock); - uv_mutex_destroy(&ssb->db_writer_lock); - tf_printf("mutexes destroyed\n"); - tf_free((void*)ssb->db_path); - tf_free(ssb->room_name); - ssb->room_name = NULL; + ssb->db_readers_count = 0; + if (ssb->db_readers) + { + tf_free(ssb->db_readers); + ssb->db_readers = NULL; + } + if (ssb->db_path) + { + tf_free((void*)ssb->db_path); + ssb->db_path = NULL; + } + if (ssb->room_name) + { + tf_free(ssb->room_name); + ssb->room_name = NULL; + } if (ssb->connection_ref_count == 0) { + uv_mutex_destroy(&ssb->db_readers_lock); + uv_mutex_destroy(&ssb->db_writer_lock); + tf_free(ssb); } } diff --git a/src/task.c b/src/task.c index 674409f3..d4f9857e 100644 --- a/src/task.c +++ b/src/task.c @@ -1418,6 +1418,7 @@ void tf_task_remove_child(tf_task_t* task, tf_taskstub_t* child) { task_child_node_t* node = *it; *it = node->next; + JS_FreeValue(task->_context, tf_taskstub_get_task_object(child)); tf_free(node); task->_child_count--; break; @@ -1809,20 +1810,25 @@ static void _tf_task_on_handle_close(uv_handle_t* handle) handle->data = NULL; } +JSValue tf_taskstub_kill(tf_taskstub_t* stub); + void tf_task_destroy(tf_task_t* task) { while (task->_children) { - task_child_node_t* node = task->_children; - task->_children = node->next; - tf_taskstub_destroy(node->stub); - tf_free(node); + for (task_child_node_t* node = task->_children; node; node = node->next) + { + JS_FreeValue(task->_context, tf_taskstub_kill(node->stub)); + + } + uv_run(&task->_loop, UV_RUN_ONCE); } if (task->_parent) { - tf_taskstub_destroy(task->_parent); + tf_taskstub_t* parent = task->_parent; task->_parent = NULL; - JS_RunGC(task->_runtime); + tf_packetstream_close(tf_taskstub_get_stream(parent)); + JS_FreeValue(task->_context, tf_taskstub_get_task_object(parent)); } while (task->_promise_count) { @@ -1911,9 +1917,15 @@ void tf_task_destroy(tf_task_t* task) uv_run(&task->_loop, UV_RUN_ONCE); } - if (uv_loop_close(&task->_loop) != 0) + int index = 0; + while (uv_loop_close(&task->_loop) != 0) { - uv_print_all_handles(&task->_loop, stdout); + if (index++ > 0) + { + tf_printf("--\n"); + uv_print_all_handles(&task->_loop, stdout); + } + uv_run(&task->_loop, UV_RUN_ONCE); } if (task->_trace) { diff --git a/src/taskstub.js.c b/src/taskstub.js.c index 8ace02c4..e389e996 100644 --- a/src/taskstub.js.c +++ b/src/taskstub.js.c @@ -205,7 +205,7 @@ static JSValue _taskstub_create(JSContext* context, JSValueConst this_val, int a JS_FreeValue(context, taskObject); } } - return result; + return JS_DupValue(context, result); } static void _taskstub_gc_mark(JSRuntime* rt, JSValueConst value, JS_MarkFunc mark_func) @@ -326,8 +326,8 @@ static void _taskstub_finalizer(JSRuntime* runtime, JSValue value) static void _taskstub_on_handle_close(uv_handle_t* handle) { tf_taskstub_t* stub = handle->data; - handle->data = NULL; tf_task_remove_child(stub->_owner, stub); + handle->data = NULL; _taskstub_cleanup(stub); } @@ -455,9 +455,8 @@ static JSValue _taskstub_execute(JSContext* context, JSValueConst this_val, int return result; } -static JSValue _taskstub_kill(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +JSValue tf_taskstub_kill(tf_taskstub_t* stub) { - tf_taskstub_t* stub = JS_GetOpaque(this_val, _classId); JSValue result = JS_UNDEFINED; if (!tf_task_get_one_proc(stub->_owner)) { @@ -472,35 +471,10 @@ static JSValue _taskstub_kill(JSContext* context, JSValueConst this_val, int arg return result; } -void tf_taskstub_destroy(tf_taskstub_t* stub) +static JSValue _taskstub_kill(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { - JSContext* context = tf_task_get_context(stub->_owner); - if (stub->_stream) - { - tf_packetstream_destroy(stub->_stream); - stub->_stream = NULL; - } - if (!JS_IsUndefined(stub->_on_exit)) - { - JS_FreeValue(context, stub->_on_exit); - stub->_on_exit = JS_UNDEFINED; - } - if (!JS_IsUndefined(stub->_on_error)) - { - JS_FreeValue(context, stub->_on_error); - stub->_on_error = JS_UNDEFINED; - } - if (!JS_IsUndefined(stub->_on_print)) - { - JS_FreeValue(context, stub->_on_print); - stub->_on_print = JS_UNDEFINED; - } - if (!JS_IsUndefined(stub->_object)) - { - JSValue object = stub->_object; - stub->_object = JS_UNDEFINED; - JS_FreeValue(context, object); - } + tf_taskstub_t* stub = JS_GetOpaque(this_val, _classId); + return tf_taskstub_kill(stub); } void tf_taskstub_on_error(tf_taskstub_t* stub, JSValue error) diff --git a/src/taskstub.js.h b/src/taskstub.js.h index d947eb61..59198d51 100644 --- a/src/taskstub.js.h +++ b/src/taskstub.js.h @@ -16,6 +16,5 @@ JSValue tf_taskstub_get_task_object(const tf_taskstub_t* stub); tf_packetstream_t* tf_taskstub_get_stream(const tf_taskstub_t* stub); tf_task_t* tf_taskstub_get_owner(const tf_taskstub_t* stub); tf_taskstub_t* tf_taskstub_create_parent(tf_task_t* task, uv_file file); -void tf_taskstub_destroy(tf_taskstub_t* stub); void tf_taskstub_on_error(tf_taskstub_t* stub, JSValue error); void tf_taskstub_on_print(tf_taskstub_t* stub, JSValue arguments);