diff --git a/src/task.c b/src/task.c index 4718d9d2..2da537af 100644 --- a/src/task.c +++ b/src/task.c @@ -56,6 +56,7 @@ typedef struct _promise_t promise_t; typedef struct _promise_t { promiseid_t id; + taskid_t task; JSValue values[2]; uint32_t stack_hash; } promise_t; @@ -165,6 +166,7 @@ static JSValue _tf_task_trace(JSContext* context, JSValueConst this_val, int arg static JSValue _tf_task_getStats(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); static JSValue _tf_task_getFile(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); +static promise_t* _tf_task_find_promise(tf_task_t* task, promiseid_t id); static void _tf_task_sendPromiseResolve(tf_task_t* from, tf_taskstub_t* to, promiseid_t promise, JSValue result); static void _tf_task_sendPromiseReject(tf_task_t* from, tf_taskstub_t* to, promiseid_t promise, JSValue result); @@ -608,6 +610,11 @@ static void _tf_task_sendPromiseExportMessage(tf_task_t* from, tf_taskstub_t* to memcpy(copy, &promise, sizeof(promise)); memcpy(copy + sizeof(promise), &exportId, sizeof(exportId)); memcpy(copy + sizeof(promise) + sizeof(exportId), buffer, size); + promise_t* found = _tf_task_find_promise(from, promise); + if (found) + { + found->task = tf_taskstub_get_id(to); + } tf_packetstream_send(tf_taskstub_get_stream(to), messageType, copy, sizeof(promise) + sizeof(exportId) + size); tf_free(buffer); tf_free(copy); @@ -1234,6 +1241,24 @@ void tf_task_reject_promise(tf_task_t* task, promiseid_t promise, JSValue value) } } +static void _promise_release_for_task(tf_task_t* task, taskid_t task_id) +{ + bool more = true; + while (more) + { + more = false; + for (int i = 0; i < task->_promise_count; i++) + { + const promise_t* promise = &task->_promises[i]; + if (promise->task == task_id) + { + tf_task_reject_promise(task, promise->id, JS_ThrowInternalError(task->_context, "Task is gone.")); + more = true; + } + } + } +} + taskid_t tf_task_allocate_task_id(tf_task_t* task, tf_taskstub_t* stub) { taskid_t id = 0; @@ -1257,6 +1282,7 @@ void tf_task_remove_child(tf_task_t* task, tf_taskstub_t* child) { _import_record_release_for_task(task, tf_taskstub_get_id(child)); _export_record_release_for_task(task, tf_taskstub_get_id(child)); + _promise_release_for_task(task, tf_taskstub_get_id(child)); for (task_child_node_t** it = &task->_children; *it; it = &(*it)->next)