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:
parent
e7791d38ff
commit
685754895b
39
src/http.c
39
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);
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include "file.js.h"
|
||||
#include "http.h"
|
||||
#include "log.h"
|
||||
#include "mem.h"
|
||||
#include "task.h"
|
||||
#include "tlscontext.js.h"
|
||||
|
52
src/ssb.c
52
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);
|
||||
}
|
||||
}
|
||||
|
28
src/task.c
28
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)
|
||||
{
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user