From 923d6f983544726a54e7865652fdd6f1f7821c56 Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Sat, 27 Jan 2024 15:45:51 +0000 Subject: [PATCH] I think that's all the leaks accounted for though not yet fixed. git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@4799 ed5197a5-7fde-0310-b194-c3ffbd925b24 --- core/app.js | 9 +++------ core/core.js | 2 +- src/http.c | 9 +++++++-- src/http.h | 2 +- src/httpd.js.c | 13 ++++++++----- src/task.c | 2 +- src/util.js.c | 1 + 7 files changed, 22 insertions(+), 16 deletions(-) diff --git a/core/app.js b/core/app.js index 67d58c20..1960a90c 100644 --- a/core/app.js +++ b/core/app.js @@ -67,11 +67,8 @@ function socket(request, response, client) { if (process && process.task) { process.task.kill(); } - } - - response.onError = async function(error) { - if (process && process.task) { - process.task.kill(); + if (process) { + process.timeout = 0; } } @@ -157,7 +154,7 @@ function socket(request, response, client) { process.lastPing = now; } - if (again) { + if (again && process.timeout) { setTimeout(ping, process.timeout); } } diff --git a/core/core.js b/core/core.js index 6ececd9a..78a71de3 100644 --- a/core/core.js +++ b/core/core.js @@ -983,7 +983,7 @@ loadSettings().then(function() { } httpd.all("/login", auth.handler); httpd.all("/app/socket", app.socket); - httpd.all("", function(request, response) { + httpd.all("", function default_http_handler(request, response) { let match; if (request.uri === "/" || request.uri === "") { try { diff --git a/src/http.c b/src/http.c index 85eecd3c..d61500cd 100644 --- a/src/http.c +++ b/src/http.c @@ -378,7 +378,7 @@ static void _http_add_body_bytes(tf_http_connection_t* connection, const void* d tf_trace_begin(connection->http->trace, connection->trace_name ? connection->trace_name : "http"); connection->callback(request); tf_trace_end(connection->http->trace); - tf_http_request_release(request); + tf_http_request_unref(request); } } } @@ -695,6 +695,10 @@ void tf_http_destroy(tf_http_t* http) tf_free(http->handlers); http->handlers_count = 0; + 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; @@ -894,7 +898,7 @@ void tf_http_request_ref(tf_http_request_t* request) request->connection->ref_count++; } -void tf_http_request_release(tf_http_request_t* request) +void tf_http_request_unref(tf_http_request_t* request) { if (--request->connection->ref_count == 0) { @@ -903,6 +907,7 @@ void tf_http_request_release(tf_http_request_t* request) _http_reset_connection(request->connection); } } + if (--request->ref_count == 0) { request->connection->request = NULL; diff --git a/src/http.h b/src/http.h index 4a74a408..fa588fce 100644 --- a/src/http.h +++ b/src/http.h @@ -47,7 +47,7 @@ void tf_http_set_user_data(tf_http_t* http, void* user_data, tf_http_cleanup_t* void* tf_http_get_user_data(tf_http_t* http); void tf_http_request_ref(tf_http_request_t* request); -void tf_http_request_release(tf_http_request_t* request); +void tf_http_request_unref(tf_http_request_t* request); const char* tf_http_request_get_header(tf_http_request_t* request, const char* name); void tf_http_request_send(tf_http_request_t* request, const void* data, size_t size); void tf_http_request_websocket_upgrade(tf_http_request_t* request); diff --git a/src/httpd.js.c b/src/httpd.js.c index 7b8cb323..6b8c8497 100644 --- a/src/httpd.js.c +++ b/src/httpd.js.c @@ -163,7 +163,7 @@ static JSValue _httpd_response_send(JSContext* context, JSValueConst this_val, i return JS_UNDEFINED; } -static void _httpd_close_callback(tf_http_request_t* request) +static void _httpd_websocket_close_callback(tf_http_request_t* request) { JSContext* context = request->context; JSValue response_object = JS_MKPTR(JS_TAG_OBJECT, request->user_data); @@ -172,7 +172,9 @@ static void _httpd_close_callback(tf_http_request_t* request) tf_util_report_error(context, response); JS_FreeValue(context, response); JS_FreeValue(context, on_close); - tf_http_request_release(request); + JS_SetPropertyStr(context, response_object, "onMessage", JS_UNDEFINED); + JS_SetPropertyStr(context, response_object, "onClose", JS_UNDEFINED); + JS_FreeValue(context, response_object); } static void _httpd_message_callback(tf_http_request_t* request, int op_code, const void* data, size_t size) @@ -217,6 +219,7 @@ static void _httpd_callback_internal(tf_http_request_t* request, bool is_websock JS_SetPropertyStr(context, request_object, "client", client); JSValue response_object = JS_NewObjectClass(context, _httpd_request_class_id); + /* The ref is owned by the JS object and will be released by the finalizer. */ tf_http_request_ref(request); JS_SetOpaque(response_object, request); JS_SetPropertyStr(context, response_object, "writeHead", JS_NewCFunction(context, _httpd_response_write_head, "writeHead", 2)); @@ -318,15 +321,15 @@ static JSValue _httpd_websocket_upgrade(JSContext* context, JSValueConst this_va tf_http_respond(request, 101, headers, headers_count, NULL, 0); request->on_message = _httpd_message_callback; - request->on_close = _httpd_close_callback; + request->on_close = _httpd_websocket_close_callback; request->context = context; request->user_data = JS_VALUE_GET_PTR(JS_DupValue(context, this_val)); } else { tf_http_respond(request, 400, NULL, 0, NULL, 0); - tf_http_request_release(request); } + tf_http_request_unref(request); return JS_UNDEFINED; } @@ -385,7 +388,7 @@ static void _httpd_finalizer(JSRuntime* runtime, JSValue value) static void _httpd_request_finalizer(JSRuntime* runtime, JSValue value) { tf_http_request_t* request = JS_GetOpaque(value, _httpd_request_class_id); - tf_http_request_release(request); + tf_http_request_unref(request); } static void _httpd_endpoint_trace(tf_http_request_t* request) diff --git a/src/task.c b/src/task.c index 4969d372..e16a92b0 100644 --- a/src/task.c +++ b/src/task.c @@ -1623,7 +1623,7 @@ tf_task_t* tf_task_create() uv_unref((uv_handle_t*)&task->trace_timer); task->gc_timer.data = task; uv_timer_init(&task->_loop, &task->gc_timer); - uv_timer_start(&task->gc_timer, _tf_task_gc_timer, 10000, 10000); + uv_timer_start(&task->gc_timer, _tf_task_gc_timer, 1000, 1000); uv_unref((uv_handle_t*)&task->gc_timer); task->idle.data = task; uv_idle_init(&task->_loop, &task->idle); diff --git a/src/util.js.c b/src/util.js.c index c00348c6..52b27c4e 100644 --- a/src/util.js.c +++ b/src/util.js.c @@ -292,6 +292,7 @@ static JSValue _util_setTimeout(JSContext* context, JSValueConst this_val, int a JS_ToInt64(context, &duration, argv[1]); if (uv_timer_start(&timeout->_timer, _util_timeoutCallback, duration, 0) != 0) { + JS_FreeValue(context, timeout->_callback); tf_free(timeout); } return JS_NULL;