From 2b41f54d3648377abea0e4d2223b16372f9eedb0 Mon Sep 17 00:00:00 2001 From: Liu Date: Wed, 16 Jan 2019 22:02:32 +0800 Subject: [PATCH] fix(worker): task queue should not be blocked when running a task --- include/LCUI/worker.h | 2 ++ src/worker.c | 45 ++++++++++++++++++++++++++++++------------- 2 files changed, 34 insertions(+), 13 deletions(-) diff --git a/include/LCUI/worker.h b/include/LCUI/worker.h index 16e910c84..1068b9a84 100644 --- a/include/LCUI/worker.h +++ b/include/LCUI/worker.h @@ -41,6 +41,8 @@ LCUI_API LCUI_Worker LCUIWorker_New(void); LCUI_API void LCUIWorker_PostTask(LCUI_Worker worker, LCUI_Task task); +LCUI_API LCUI_Task LCUIWorker_GetTask(LCUI_Worker worker); + LCUI_API LCUI_BOOL LCUIWorker_RunTask(LCUI_Worker worker); LCUI_API int LCUIWorker_RunAsync(LCUI_Worker worker); diff --git a/src/worker.c b/src/worker.c index 2f5ab010f..c237509f0 100644 --- a/src/worker.c +++ b/src/worker.c @@ -69,24 +69,35 @@ void LCUIWorker_PostTask(LCUI_Worker worker, LCUI_Task task) LCUIMutex_Unlock(&worker->mutex); } -LCUI_BOOL LCUIWorker_RunTask(LCUI_Worker worker) +LCUI_Task LCUIWorker_GetTask(LCUI_Worker worker) { LCUI_Task task; LinkedListNode *node; - LCUIMutex_Lock(&worker->mutex); + node = LinkedList_GetNode(&worker->tasks, 0); - if (node) { - task = node->data; - LinkedList_Unlink(&worker->tasks, node); - LCUIMutex_Unlock(&worker->mutex); - LCUITask_Run(task); - LCUITask_Destroy(task); - free(task); - free(node); - return TRUE; + if (!node) { + return NULL; } + task = node->data; + LinkedList_Unlink(&worker->tasks, node); + free(node); + return task; +} + +LCUI_BOOL LCUIWorker_RunTask(LCUI_Worker worker) +{ + LCUI_Task task; + + LCUIMutex_Lock(&worker->mutex); + task = LCUIWorker_GetTask(worker); LCUIMutex_Unlock(&worker->mutex); - return FALSE; + if (!task) { + return FALSE; + } + LCUITask_Run(task); + LCUITask_Destroy(task); + free(task); + return TRUE; } static void OnDeleteTask(void *arg) @@ -106,10 +117,18 @@ static void LCUIWorker_ExecDestroy(LCUI_Worker worker) static void LCUIWorker_Thread(void *arg) { + LCUI_Task task; LCUI_Worker worker = arg; + LCUIMutex_Lock(&worker->mutex); while (worker->active) { - if (LCUIWorker_RunTask(worker)) { + task = LCUIWorker_GetTask(worker); + if (task) { + LCUIMutex_Unlock(&worker->mutex); + LCUITask_Run(task); + LCUITask_Destroy(task); + free(task); + LCUIMutex_Lock(&worker->mutex); continue; } if (worker->active) {