# HG changeset patch # User Olaf Wintermann # Date 1768070650 -3600 # Node ID f3e2811ecf3a490e9bfd2dbd67c46d4d6bed38e5 # Parent db47e814b4c5bcca799ef22e5457485e4c1cf0e1 add function for buffering mainthread calls diff -r db47e814b4c5 -r f3e2811ecf3a ui/cocoa/toolkit.m --- a/ui/cocoa/toolkit.m Thu Jan 08 18:17:06 2026 +0100 +++ b/ui/cocoa/toolkit.m Sat Jan 10 19:44:10 2026 +0100 @@ -174,6 +174,11 @@ @end void ui_call_mainthread(ui_threadfunc tf, void* td) { + if(uic_mainthread_calls_is_buffered()) { + uic_add_buffered_mainthread_call(tf, td); + return; + } + UiAppCallback *cb = [[UiAppCallback alloc]initWithCallback:tf userdata:td]; [cb callMainThread]; } diff -r db47e814b4c5 -r f3e2811ecf3a ui/common/threadpool.c --- a/ui/common/threadpool.c Thu Jan 08 18:17:06 2026 +0100 +++ b/ui/common/threadpool.c Sat Jan 10 19:44:10 2026 +0100 @@ -30,6 +30,7 @@ #include "threadpool.h" #include "context.h" +#include #include #include @@ -38,6 +39,56 @@ static threadpool_job kill_job; + + +static pthread_mutex_t mc_buffer_mutex; +static CxList *mainthread_call_buffer; +static volatile int mainthread_call_buffered = 0; + +typedef struct UiMainCall { + ui_threadfunc func; + void *data; +} UiMainCall; + +void uic_init_threads(void) { + pthread_mutex_init(&mc_buffer_mutex, NULL); + mainthread_call_buffer = cxLinkedListCreate(NULL, sizeof(UiMainCall)); +} + +int uic_mainthread_calls_is_buffered(void) { + return mainthread_call_buffered; +} + +void uic_add_buffered_mainthread_call(ui_threadfunc func, void *data) { + pthread_mutex_lock(&mc_buffer_mutex); + UiMainCall call; + call.func = func; + call.data = data; + cxListAdd(mainthread_call_buffer, &call); + pthread_mutex_unlock(&mc_buffer_mutex); +} + + +void ui_buffer_mainthread_calls(UiBool enable_buffering) { + mainthread_call_buffered = enable_buffering; + if(!enable_buffering) { + ui_exec_buffered_mainthread_calls(); + } +} +void ui_exec_buffered_mainthread_calls(void) { + pthread_mutex_lock(&mc_buffer_mutex); + CxIterator i = cxListIterator(mainthread_call_buffer); + cx_foreach(UiMainCall *, call, i) { + if(call->func) { + call->func(call->data); + } + } + cxListClear(mainthread_call_buffer); + pthread_mutex_unlock(&mc_buffer_mutex); +} + + + UiThreadpool* threadpool_new(int min, int max) { UiThreadpool *pool = malloc(sizeof(UiThreadpool)); pool->queue = ui_queue_create(); diff -r db47e814b4c5 -r f3e2811ecf3a ui/common/threadpool.h --- a/ui/common/threadpool.h Thu Jan 08 18:17:06 2026 +0100 +++ b/ui/common/threadpool.h Sat Jan 10 19:44:10 2026 +0100 @@ -39,6 +39,10 @@ extern "C" { #endif +void uic_init_threads(void); +int uic_mainthread_calls_is_buffered(void); +void uic_add_buffered_mainthread_call(ui_threadfunc func, void *data); + typedef struct UiQueueElm UiQueueElm; typedef struct UiQueue UiQueue; diff -r db47e814b4c5 -r f3e2811ecf3a ui/gtk/toolkit.c --- a/ui/gtk/toolkit.c Thu Jan 08 18:17:06 2026 +0100 +++ b/ui/gtk/toolkit.c Sat Jan 10 19:44:10 2026 +0100 @@ -76,6 +76,7 @@ uic_toolbar_init(); ui_image_init(); uic_load_app_properties(); + uic_init_threads(); #if GTK_MAJOR_VERSION >= 4 scale_factor = 1; // TODO @@ -203,6 +204,11 @@ } void ui_call_mainthread(ui_threadfunc tf, void* td) { + if(uic_mainthread_calls_is_buffered()) { + uic_add_buffered_mainthread_call(tf, td); + return; + } + UiJob *job = malloc(sizeof(UiJob)); job->job_func = tf; job->job_data = td; diff -r db47e814b4c5 -r f3e2811ecf3a ui/motif/toolkit.c --- a/ui/motif/toolkit.c Thu Jan 08 18:17:06 2026 +0100 +++ b/ui/motif/toolkit.c Sat Jan 10 19:44:10 2026 +0100 @@ -221,6 +221,11 @@ } void ui_call_mainthread(ui_threadfunc tf, void* td) { + if(uic_mainthread_calls_is_buffered()) { + uic_add_buffered_mainthread_call(tf, td); + return; + } + UiJob *job = malloc(sizeof(UiJob)); memset(job, 0, sizeof(UiJob)); job->job_func = tf; diff -r db47e814b4c5 -r f3e2811ecf3a ui/ui/toolkit.h --- a/ui/ui/toolkit.h Thu Jan 08 18:17:06 2026 +0100 +++ b/ui/ui/toolkit.h Sat Jan 10 19:44:10 2026 +0100 @@ -556,6 +556,10 @@ UIEXPORT void ui_job(UiObject *obj, ui_threadfunc tf, void *td, ui_callback f, void *fd); UIEXPORT void ui_call_mainthread(ui_threadfunc tf, void* td); + +UIEXPORT void ui_buffer_mainthread_calls(UiBool enable_buffering); +UIEXPORT void ui_exec_buffered_mainthread_calls(void); + UIEXPORT UiThreadpool* ui_threadpool_create(int nthreads); UIEXPORT void ui_threadpool_destroy(UiThreadpool* pool); UIEXPORT void ui_threadpool_job(UiThreadpool* pool, UiObject* obj, ui_threadfunc tf, void* td, ui_callback f, void* fd);