From 0693a2315fa7dd9b45146577fb7223a96ae22f3a Mon Sep 17 00:00:00 2001 From: Cory McWilliams Date: Tue, 20 Aug 2024 12:26:34 -0400 Subject: [PATCH] Fix async job starvation if everything is running too slowly. --- src/task.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/task.c b/src/task.c index b0d54f95..0af81a2f 100644 --- a/src/task.c +++ b/src/task.c @@ -140,6 +140,7 @@ typedef struct _tf_task_t float idle_percent; float thread_percent; + uv_async_t run_jobs_async; uv_idle_t idle; uv_prepare_t prepare; uv_signal_t sig_term; @@ -1543,6 +1544,15 @@ static void _tf_task_run_jobs_prepare(uv_prepare_t* prepare) } } +static void _tf_task_run_jobs_async(uv_async_t* async) +{ + tf_task_t* task = async->data; + if (_tf_task_run_jobs(task)) + { + uv_async_send(async); + } +} + static JSModuleDef* _tf_task_module_loader(JSContext* context, const char* module_name, void* opaque) { tf_task_t* task = opaque; @@ -1643,6 +1653,9 @@ tf_task_t* tf_task_create() uv_prepare_init(&task->_loop, &task->prepare); uv_unref((uv_handle_t*)&task->prepare); uv_idle_start(&task->idle, _tf_task_run_jobs_idle); + task->run_jobs_async.data = task; + uv_async_init(&task->_loop, &task->run_jobs_async, _tf_task_run_jobs_async); + uv_unref((uv_handle_t*)&task->run_jobs_async); task->sig_term.data = task; uv_signal_init(&task->_loop, &task->sig_term); uv_signal_start(&task->sig_term, _tf_task_signal_shutdown, SIGTERM); @@ -1912,12 +1925,13 @@ void tf_task_destroy(tf_task_t* task) } uv_close((uv_handle_t*)&task->idle, _tf_task_on_handle_close); uv_close((uv_handle_t*)&task->prepare, _tf_task_on_handle_close); + uv_close((uv_handle_t*)&task->run_jobs_async, _tf_task_on_handle_close); uv_signal_stop(&task->sig_term); uv_close((uv_handle_t*)&task->sig_term, _tf_task_on_handle_close); uv_signal_stop(&task->sig_int); uv_close((uv_handle_t*)&task->sig_int, _tf_task_on_handle_close); - while (task->trace_timer.data || task->gc_timer.data || task->idle.data || task->prepare.data || task->sig_term.data || task->sig_int.data) + while (task->trace_timer.data || task->gc_timer.data || task->idle.data || task->prepare.data || task->run_jobs_async.data || task->sig_term.data || task->sig_int.data) { uv_run(&task->_loop, UV_RUN_ONCE); }