Have we achieved clean shutdown?

git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4841 ed5197a5-7fde-0310-b194-c3ffbd925b24
This commit is contained in:
Cory McWilliams 2024-02-13 23:07:36 +00:00
parent e7791d38ff
commit 685754895b
6 changed files with 84 additions and 75 deletions

View File

@ -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);
}
}

View File

@ -2,6 +2,7 @@
#include "file.js.h"
#include "http.h"
#include "log.h"
#include "mem.h"
#include "task.h"
#include "tlscontext.js.h"

View File

@ -2376,8 +2376,12 @@ void tf_ssb_destroy(tf_ssb_t* ssb)
{
tf_printf("tf_ssb_destroy\n");
ssb->shutting_down = true;
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;
}
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]);
}
ssb->db_readers_count = 0;
if (ssb->db_readers)
{
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");
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);
}
}

View File

@ -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,10 +1917,16 @@ 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)
{
if (index++ > 0)
{
tf_printf("--\n");
uv_print_all_handles(&task->_loop, stdout);
}
uv_run(&task->_loop, UV_RUN_ONCE);
}
if (task->_trace)
{
tf_trace_destroy(task->_trace);

View File

@ -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)

View File

@ -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);