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");
|
_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)
|
if (http->connections_count == 0)
|
||||||
{
|
{
|
||||||
tf_free(http->connections);
|
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++)
|
for (int i = 0; i < http->listeners_count; i++)
|
||||||
{
|
{
|
||||||
tf_http_listener_t* listener = http->listeners[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);
|
uv_close((uv_handle_t*)&listener->tcp, _http_free_listener_on_close);
|
||||||
}
|
}
|
||||||
tf_free(http->listeners);
|
tf_free(http->listeners);
|
||||||
@ -727,20 +748,10 @@ void tf_http_destroy(tf_http_t* http)
|
|||||||
tf_free((void*)http->handlers[i].pattern);
|
tf_free((void*)http->handlers[i].pattern);
|
||||||
http->handlers[i].pattern = NULL;
|
http->handlers[i].pattern = NULL;
|
||||||
}
|
}
|
||||||
if (http->handlers[i].cleanup)
|
|
||||||
{
|
|
||||||
http->handlers[i].cleanup(http->handlers[i].user_data);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
tf_free(http->handlers);
|
tf_free(http->handlers);
|
||||||
http->handlers_count = 0;
|
http->handlers_count = 0;
|
||||||
|
|
||||||
if (http->user_data_cleanup)
|
|
||||||
{
|
|
||||||
http->user_data_cleanup(http->user_data);
|
|
||||||
http->user_data = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
tf_free(http);
|
tf_free(http);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "file.js.h"
|
#include "file.js.h"
|
||||||
#include "http.h"
|
#include "http.h"
|
||||||
|
#include "log.h"
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "task.h"
|
#include "task.h"
|
||||||
#include "tlscontext.js.h"
|
#include "tlscontext.js.h"
|
||||||
|
38
src/ssb.c
38
src/ssb.c
@ -2376,8 +2376,12 @@ void tf_ssb_destroy(tf_ssb_t* ssb)
|
|||||||
{
|
{
|
||||||
tf_printf("tf_ssb_destroy\n");
|
tf_printf("tf_ssb_destroy\n");
|
||||||
ssb->shutting_down = true;
|
ssb->shutting_down = true;
|
||||||
|
|
||||||
|
if (ssb->connections_tracker)
|
||||||
|
{
|
||||||
tf_ssb_connections_destroy(ssb->connections_tracker);
|
tf_ssb_connections_destroy(ssb->connections_tracker);
|
||||||
ssb->connections_tracker = NULL;
|
ssb->connections_tracker = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (ssb->broadcast_listener.data && !uv_is_closing((uv_handle_t*)&ssb->broadcast_listener))
|
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_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_printf("Closing connections.\n");
|
||||||
tf_ssb_connection_t* connection = ssb->connections;
|
tf_ssb_connection_t* connection = ssb->connections;
|
||||||
while (connection)
|
while (connection)
|
||||||
{
|
{
|
||||||
tf_ssb_connection_t* next = connection->next;
|
tf_ssb_connection_t* next = connection->next;
|
||||||
tf_printf("close %p\n", connection);
|
|
||||||
tf_ssb_connection_close(connection);
|
tf_ssb_connection_close(connection);
|
||||||
connection = next;
|
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("uv_loop_close: %s\n", uv_strerror(r));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tf_printf("loop closed\n");
|
tf_printf("uv loop closed.\n");
|
||||||
if (ssb->own_context)
|
if (ssb->own_context)
|
||||||
{
|
{
|
||||||
JS_FreeContext(ssb->context);
|
JS_FreeContext(ssb->context);
|
||||||
JS_FreeRuntime(ssb->runtime);
|
JS_FreeRuntime(ssb->runtime);
|
||||||
|
ssb->own_context = false;
|
||||||
}
|
}
|
||||||
|
if (ssb->db_writer)
|
||||||
|
{
|
||||||
sqlite3_close(ssb->db_writer);
|
sqlite3_close(ssb->db_writer);
|
||||||
|
ssb->db_writer = NULL;
|
||||||
|
}
|
||||||
while (ssb->broadcasts)
|
while (ssb->broadcasts)
|
||||||
{
|
{
|
||||||
tf_ssb_broadcast_t* broadcast = 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]);
|
sqlite3_close(ssb->db_readers[i]);
|
||||||
}
|
}
|
||||||
|
ssb->db_readers_count = 0;
|
||||||
|
if (ssb->db_readers)
|
||||||
|
{
|
||||||
tf_free(ssb->db_readers);
|
tf_free(ssb->db_readers);
|
||||||
tf_printf("destroying mutexes\n");
|
ssb->db_readers = NULL;
|
||||||
uv_mutex_destroy(&ssb->db_readers_lock);
|
}
|
||||||
uv_mutex_destroy(&ssb->db_writer_lock);
|
if (ssb->db_path)
|
||||||
tf_printf("mutexes destroyed\n");
|
{
|
||||||
tf_free((void*)ssb->db_path);
|
tf_free((void*)ssb->db_path);
|
||||||
|
ssb->db_path = NULL;
|
||||||
|
}
|
||||||
|
if (ssb->room_name)
|
||||||
|
{
|
||||||
tf_free(ssb->room_name);
|
tf_free(ssb->room_name);
|
||||||
ssb->room_name = NULL;
|
ssb->room_name = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (ssb->connection_ref_count == 0)
|
if (ssb->connection_ref_count == 0)
|
||||||
{
|
{
|
||||||
|
uv_mutex_destroy(&ssb->db_readers_lock);
|
||||||
|
uv_mutex_destroy(&ssb->db_writer_lock);
|
||||||
|
|
||||||
tf_free(ssb);
|
tf_free(ssb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
26
src/task.c
26
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;
|
task_child_node_t* node = *it;
|
||||||
*it = node->next;
|
*it = node->next;
|
||||||
|
JS_FreeValue(task->_context, tf_taskstub_get_task_object(child));
|
||||||
tf_free(node);
|
tf_free(node);
|
||||||
task->_child_count--;
|
task->_child_count--;
|
||||||
break;
|
break;
|
||||||
@ -1809,20 +1810,25 @@ static void _tf_task_on_handle_close(uv_handle_t* handle)
|
|||||||
handle->data = NULL;
|
handle->data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JSValue tf_taskstub_kill(tf_taskstub_t* stub);
|
||||||
|
|
||||||
void tf_task_destroy(tf_task_t* task)
|
void tf_task_destroy(tf_task_t* task)
|
||||||
{
|
{
|
||||||
while (task->_children)
|
while (task->_children)
|
||||||
{
|
{
|
||||||
task_child_node_t* node = task->_children;
|
for (task_child_node_t* node = task->_children; node; node = node->next)
|
||||||
task->_children = node->next;
|
{
|
||||||
tf_taskstub_destroy(node->stub);
|
JS_FreeValue(task->_context, tf_taskstub_kill(node->stub));
|
||||||
tf_free(node);
|
|
||||||
|
}
|
||||||
|
uv_run(&task->_loop, UV_RUN_ONCE);
|
||||||
}
|
}
|
||||||
if (task->_parent)
|
if (task->_parent)
|
||||||
{
|
{
|
||||||
tf_taskstub_destroy(task->_parent);
|
tf_taskstub_t* parent = task->_parent;
|
||||||
task->_parent = NULL;
|
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)
|
while (task->_promise_count)
|
||||||
{
|
{
|
||||||
@ -1911,10 +1917,16 @@ void tf_task_destroy(tf_task_t* task)
|
|||||||
uv_run(&task->_loop, UV_RUN_ONCE);
|
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_print_all_handles(&task->_loop, stdout);
|
||||||
}
|
}
|
||||||
|
uv_run(&task->_loop, UV_RUN_ONCE);
|
||||||
|
}
|
||||||
if (task->_trace)
|
if (task->_trace)
|
||||||
{
|
{
|
||||||
tf_trace_destroy(task->_trace);
|
tf_trace_destroy(task->_trace);
|
||||||
|
@ -205,7 +205,7 @@ static JSValue _taskstub_create(JSContext* context, JSValueConst this_val, int a
|
|||||||
JS_FreeValue(context, taskObject);
|
JS_FreeValue(context, taskObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return JS_DupValue(context, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void _taskstub_gc_mark(JSRuntime* rt, JSValueConst value, JS_MarkFunc mark_func)
|
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)
|
static void _taskstub_on_handle_close(uv_handle_t* handle)
|
||||||
{
|
{
|
||||||
tf_taskstub_t* stub = handle->data;
|
tf_taskstub_t* stub = handle->data;
|
||||||
handle->data = NULL;
|
|
||||||
tf_task_remove_child(stub->_owner, stub);
|
tf_task_remove_child(stub->_owner, stub);
|
||||||
|
handle->data = NULL;
|
||||||
_taskstub_cleanup(stub);
|
_taskstub_cleanup(stub);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -455,9 +455,8 @@ static JSValue _taskstub_execute(JSContext* context, JSValueConst this_val, int
|
|||||||
return result;
|
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;
|
JSValue result = JS_UNDEFINED;
|
||||||
if (!tf_task_get_one_proc(stub->_owner))
|
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;
|
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);
|
tf_taskstub_t* stub = JS_GetOpaque(this_val, _classId);
|
||||||
if (stub->_stream)
|
return tf_taskstub_kill(stub);
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tf_taskstub_on_error(tf_taskstub_t* stub, JSValue error)
|
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_packetstream_t* tf_taskstub_get_stream(const tf_taskstub_t* stub);
|
||||||
tf_task_t* tf_taskstub_get_owner(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);
|
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_error(tf_taskstub_t* stub, JSValue error);
|
||||||
void tf_taskstub_on_print(tf_taskstub_t* stub, JSValue arguments);
|
void tf_taskstub_on_print(tf_taskstub_t* stub, JSValue arguments);
|
||||||
|
Loading…
Reference in New Issue
Block a user