From 0bcc7d8c59adfec299636320a70c053b3015c3d5 Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Fri, 14 Jan 2022 03:05:37 +0000 Subject: [PATCH] Always fetch the promise JSValue and ID when we allocate one. Make it impossible that we've freed it before we return it. Hopefully fixes leaks. Definitely not worse for performance. git-svn-id: https://www.unprompted.com/svn/projects/tildefriends/trunk@3758 ed5197a5-7fde-0310-b194-c3ffbd925b24 --- src/file.js.c | 30 ++++++++++++++++-------------- src/socket.js.c | 36 +++++++++++++++--------------------- src/task.c | 9 +++++---- src/task.h | 2 +- src/taskstub.js.c | 10 ++++++---- 5 files changed, 43 insertions(+), 44 deletions(-) diff --git a/src/file.js.c b/src/file.js.c index 074ea419..ed8a6c45 100644 --- a/src/file.js.c +++ b/src/file.js.c @@ -114,7 +114,8 @@ static JSValue _file_read_file(JSContext* context, JSValueConst this_val, int ar void* task = JS_GetContextOpaque(context); const char* file_name = JS_ToCString(context, argv[0]); - promiseid_t promise = tf_task_allocate_promise(task); + promiseid_t promise = -1; + JSValue promise_value = tf_task_allocate_promise(task, &promise); uv_fs_t* req = malloc(sizeof(uv_fs_t) + k_file_read_max); *req = (uv_fs_t) { @@ -126,7 +127,7 @@ static JSValue _file_read_file(JSContext* context, JSValueConst this_val, int ar tf_task_reject_promise(task, promise, JS_ThrowInternalError(context, uv_strerror(result))); } JS_FreeCString(context, file_name); - return tf_task_get_promise(task, promise); + return promise_value; } static void _file_write_write_callback(uv_fs_t* req) @@ -189,8 +190,8 @@ static JSValue _file_write_file(JSContext* context, JSValueConst this_val, int a buffer = (uint8_t*)JS_ToCStringLen(context, &size, argv[1]); } - promiseid_t promise = tf_task_allocate_promise(task); - JSValue promise_value = tf_task_get_promise(task, promise); + promiseid_t promise = -1; + JSValue promise_value = tf_task_allocate_promise(task, &promise); uv_fs_t* req = malloc(sizeof(uv_fs_t) + sizeof(size_t) + size); *req = (uv_fs_t) { @@ -234,8 +235,8 @@ static JSValue _file_rename_file(JSContext* context, JSValueConst this_val, int void* task = JS_GetContextOpaque(context); const char* old_name = JS_ToCString(context, argv[0]); const char* new_name = JS_ToCString(context, argv[1]); - promiseid_t promise = tf_task_allocate_promise(task); - JSValue promise_value = tf_task_get_promise(task, promise); + promiseid_t promise = -1; + JSValue promise_value = tf_task_allocate_promise(task, &promise); uv_fs_t* req = malloc(sizeof(uv_fs_t)); *req = (uv_fs_t) { @@ -255,8 +256,8 @@ static JSValue _file_unlink_file(JSContext* context, JSValueConst this_val, int { void* task = JS_GetContextOpaque(context); const char* file_name = JS_ToCString(context, argv[0]); - promiseid_t promise = tf_task_allocate_promise(task); - JSValue promise_value = tf_task_get_promise(task, promise); + promiseid_t promise = -1; + JSValue promise_value = tf_task_allocate_promise(task, &promise); uv_fs_t* req = malloc(sizeof(uv_fs_t)); *req = (uv_fs_t) { @@ -276,8 +277,8 @@ JSValue _file_make_directory(JSContext* context, JSValueConst this_val, int argc void* task = JS_GetContextOpaque(context); const char* directory = JS_ToCString(context, argv[0]); - promiseid_t promise = tf_task_allocate_promise(task); - JSValue promise_value = tf_task_get_promise(task, promise); + promiseid_t promise = -1; + JSValue promise_value = tf_task_allocate_promise(task, &promise); uv_fs_t* req = malloc(sizeof(uv_fs_t)); *req = (uv_fs_t) { @@ -297,8 +298,8 @@ JSValue _file_remove_directory(JSContext* context, JSValueConst this_val, int ar void* task = JS_GetContextOpaque(context); const char* directory = JS_ToCString(context, argv[0]); - promiseid_t promise = tf_task_allocate_promise(task); - JSValue promise_value = tf_task_get_promise(task, promise); + promiseid_t promise = -1; + JSValue promise_value = tf_task_allocate_promise(task, &promise); uv_fs_t* req = malloc(sizeof(uv_fs_t)); *req = (uv_fs_t) { @@ -317,7 +318,8 @@ JSValue _file_stat(JSContext* context, JSValueConst this_val, int argc, JSValueC { void* task = JS_GetContextOpaque(context); const char* path = JS_ToCString(context, argv[0]); - promiseid_t promise = tf_task_allocate_promise(task); + promiseid_t promise = -1; + JSValue promise_value = tf_task_allocate_promise(task, &promise); file_stat_t* data = malloc(sizeof(file_stat_t)); data->_task = task; @@ -332,7 +334,7 @@ JSValue _file_stat(JSContext* context, JSValueConst this_val, int argc, JSValueC free(data); } JS_FreeCString(context, path); - return tf_task_get_promise(task, promise); + return promise_value; } static double _time_spec_to_double(const uv_timespec_t* time_spec) diff --git a/src/socket.js.c b/src/socket.js.c index 2461955e..af1bd87a 100644 --- a/src/socket.js.c +++ b/src/socket.js.c @@ -259,8 +259,7 @@ JSValue _socket_startTls(JSContext* context, JSValueConst this_val, int argc, JS { tf_tls_session_start_connect(socket->_tls); } - socket->_startTlsPromise = tf_task_allocate_promise(socket->_task); - JSValue result = tf_task_get_promise(socket->_task, socket->_startTlsPromise); + JSValue result = tf_task_allocate_promise(socket->_task, &socket->_startTlsPromise); _socket_processOutgoingTls(socket); return result; } @@ -349,8 +348,7 @@ JSValue _socket_bind(JSContext* context, JSValueConst this_val, int argc, JSValu }; data->resolver.data = data; data->socket = socket; - data->promise = tf_task_allocate_promise(socket->_task); - + JSValue promise = tf_task_allocate_promise(socket->_task, &data->promise); int result = uv_getaddrinfo(tf_task_get_loop(socket->_task), &data->resolver, _socket_onResolvedForBind, node, port, &hints); if (result != 0) { @@ -359,7 +357,7 @@ JSValue _socket_bind(JSContext* context, JSValueConst this_val, int argc, JSValu tf_task_reject_promise(socket->_task, data->promise, JS_ThrowInternalError(tf_task_get_context(socket->_task), error)); free(data); } - return tf_task_get_promise(socket->_task, data->promise); + return promise; } void _socket_onResolvedForBind(uv_getaddrinfo_t* resolver, int status, struct addrinfo* result) @@ -397,8 +395,6 @@ JSValue _socket_connect(JSContext* context, JSValueConst this_val, int argc, JSV strncpy(socket->_peerName, node, sizeof(socket->_peerName) - 1); - promiseid_t promise = tf_task_allocate_promise(socket->_task); - socket_resolve_data_t* data = malloc(sizeof(socket_resolve_data_t)); memset(data, 0, sizeof(*data)); struct addrinfo hints = { @@ -408,20 +404,19 @@ JSValue _socket_connect(JSContext* context, JSValueConst this_val, int argc, JSV }; data->resolver.data = data; data->socket = socket; - data->promise = promise; - + JSValue promise = tf_task_allocate_promise(socket->_task, &data->promise); int result = uv_getaddrinfo(tf_task_get_loop(socket->_task), &data->resolver, _socket_onResolvedForConnect, node, port, &hints); if (result != 0) { char error[256]; snprintf(error, sizeof(error), "uv_getaddrinfo: %s", uv_strerror(result)); - tf_task_reject_promise(socket->_task, promise, JS_ThrowInternalError(context, "%s", error)); + tf_task_reject_promise(socket->_task, data->promise, JS_ThrowInternalError(context, "%s", error)); free(data); } JS_FreeCString(context, node); JS_FreeCString(context, port); - return tf_task_get_promise(socket->_task, promise); + return promise; } void _socket_onResolvedForConnect(uv_getaddrinfo_t* resolver, int status, struct addrinfo* result) @@ -515,8 +510,8 @@ JSValue _socket_accept(JSContext* context, JSValueConst this_val, int argc, JSVa socket_t* client = _socket_create_internal(context); client->_direction = kAccept; - promiseid_t promise = tf_task_allocate_promise(socket->_task); - JSValue result = tf_task_get_promise(socket->_task, promise); + promiseid_t promise; + JSValue result = tf_task_allocate_promise(socket->_task, &promise); int status = uv_accept((uv_stream_t*)&socket->_socket, (uv_stream_t*)&client->_socket); if (status == 0) { @@ -537,8 +532,7 @@ JSValue _socket_close(JSContext* context, JSValueConst this_val, int argc, JSVal socket_t* socket = JS_GetOpaque(this_val, _classId); if (socket->_closePromise == -1) { - socket->_closePromise = tf_task_allocate_promise(socket->_task); - JSValue result = tf_task_get_promise(socket->_task, socket->_closePromise); + JSValue result = tf_task_allocate_promise(socket->_task, &socket->_closePromise); _socket_close_internal(socket); return result; } @@ -548,8 +542,8 @@ JSValue _socket_close(JSContext* context, JSValueConst this_val, int argc, JSVal JSValue _socket_shutdown(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { socket_t* socket = JS_GetOpaque(this_val, _classId); - promiseid_t promise = tf_task_allocate_promise(socket->_task); - JSValue result = tf_task_get_promise(socket->_task, promise); + promiseid_t promise = -1; + JSValue result = tf_task_allocate_promise(socket->_task, &promise); if (socket->_tls) { _socket_processTlsShutdown(socket, promise); @@ -610,8 +604,8 @@ JSValue _socket_read(JSContext* context, JSValueConst this_val, int argc, JSValu socket_t* socket = JS_GetOpaque(this_val, _classId); socket->_onRead = JS_DupValue(context, argv[0]); int result = uv_read_start((uv_stream_t*)&socket->_socket, _socket_allocateBuffer, _socket_onRead); - promiseid_t promise = tf_task_allocate_promise(socket->_task); - JSValue read_result = tf_task_get_promise(socket->_task, promise); + promiseid_t promise = -1; + JSValue read_result = tf_task_allocate_promise(socket->_task, &promise); if (result != 0) { char error[256]; @@ -822,8 +816,8 @@ static int _socket_write_tls(socket_t* socket, promiseid_t promise, const char* JSValue _socket_write(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { socket_t* socket = JS_GetOpaque(this_val, _classId); - promiseid_t promise = tf_task_allocate_promise(socket->_task); - JSValue write_result = tf_task_get_promise(socket->_task, promise); + promiseid_t promise = -1; + JSValue write_result = tf_task_allocate_promise(socket->_task, &promise); if (!JS_IsUndefined(argv[0])) { if (socket->_tls) diff --git a/src/task.c b/src/task.c index 5470df52..40ab05eb 100644 --- a/src/task.c +++ b/src/task.c @@ -406,9 +406,9 @@ static JSValue _import_call(JSContext* context, JSValueConst func_obj, JSValueCo tf_taskstub_t* recipient = _tf_task_get_stub(sender, import->_task); if (recipient) { - promiseid_t promise = tf_task_allocate_promise(sender); + promiseid_t promise = -1; + result = tf_task_allocate_promise(sender, &promise); _tf_task_sendPromiseExportMessage(sender, recipient, kInvokeExport, promise, import->_export, array); - result = tf_task_get_promise(sender, promise); } else { @@ -1120,7 +1120,7 @@ static void _tf_task_free_promise(tf_task_t* task, promiseid_t id) } } -promiseid_t tf_task_allocate_promise(tf_task_t* task) +JSValue tf_task_allocate_promise(tf_task_t* task, promiseid_t* out_promise) { promiseid_t promiseId; do { @@ -1142,7 +1142,8 @@ promiseid_t tf_task_allocate_promise(tf_task_t* task) task->_promises[index] = promise; task->_promise_count++; _tf_task_trace_promises(task); - return promiseId; + *out_promise = promiseId; + return promise.values[0]; } void tf_task_resolve_promise(tf_task_t* task, promiseid_t promise, JSValue value) diff --git a/src/task.h b/src/task.h index a1721609..a1ba7ee2 100644 --- a/src/task.h +++ b/src/task.h @@ -56,7 +56,7 @@ tf_trace_t* tf_task_get_trace(tf_task_t* task); void tf_task_run_jobs(tf_task_t* task); const char* tf_task_get_name(tf_task_t* task); -promiseid_t tf_task_allocate_promise(tf_task_t* task); +JSValue tf_task_allocate_promise(tf_task_t* task, promiseid_t* out_promise); void tf_task_reject_promise(tf_task_t* task, promiseid_t promise, JSValue error); void tf_task_resolve_promise(tf_task_t* task, promiseid_t promise, JSValue result); JSValue tf_task_get_promise(tf_task_t* task, promiseid_t promise); diff --git a/src/taskstub.js.c b/src/taskstub.js.c index 3044fe82..9caa9916 100644 --- a/src/taskstub.js.c +++ b/src/taskstub.js.c @@ -284,9 +284,10 @@ static void _taskstub_on_process_exit(uv_process_t* process, int64_t status, int static JSValue _taskstub_getExports(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { tf_taskstub_t* stub = JS_GetOpaque(this_val, _classId); - promiseid_t promise = tf_task_allocate_promise(stub->_owner); + promiseid_t promise = -1; + JSValue result = tf_task_allocate_promise(stub->_owner, &promise); tf_task_send_promise_message(stub->_owner, (tf_taskstub_t*)stub, kGetExports, promise, JS_UNDEFINED); - return tf_task_get_promise(stub->_owner, promise); + return result; } static JSValue _taskstub_setImports(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) @@ -366,9 +367,10 @@ static JSValue _taskstub_activate(JSContext* context, JSValueConst this_val, int static JSValue _taskstub_execute(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { tf_taskstub_t* stub = JS_GetOpaque(this_val, _classId); - promiseid_t promise = tf_task_allocate_promise(stub->_owner); + promiseid_t promise = -1; + JSValue result = tf_task_allocate_promise(stub->_owner, &promise); tf_task_send_promise_message(stub->_owner, (tf_taskstub_t*)stub, kExecute, promise, argv[0]); - return tf_task_get_promise(stub->_owner, promise); + return result; } static JSValue _taskstub_kill(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv)