Sat, 06 Dec 2025 15:24:13 +0100
add main event loop (Server)
--- a/ui/common/threadpool.c Sat Dec 06 14:12:11 2025 +0100 +++ b/ui/common/threadpool.c Sat Dec 06 15:24:13 2025 +0100 @@ -40,16 +40,11 @@ UiThreadpool* threadpool_new(int min, int max) { UiThreadpool *pool = malloc(sizeof(UiThreadpool)); - pool->queue = NULL; - pool->queue_len = 0; + pool->queue = ui_queue_create(); pool->num_idle = 0; pool->min_threads = min; pool->max_threads = max; - pthread_mutex_init(&pool->queue_lock, NULL); - pthread_mutex_init(&pool->avlbl_lock, NULL); - pthread_cond_init(&pool->available, NULL); - return pool; } @@ -93,69 +88,17 @@ } threadpool_job* threadpool_get_job(UiThreadpool *pool) { - pthread_mutex_lock(&pool->queue_lock); - - threadpool_job *job = NULL; - pool->num_idle++; - while(job == NULL) { - if(pool->queue_len == 0) { - pthread_cond_wait(&pool->available, &pool->queue_lock); - continue; - } else { - pool_queue_t *q = pool->queue; - job = q->job; - pool->queue = q->next; - pool->queue_len--; - free(q); - } - } - pool->num_idle--; - - pthread_mutex_unlock(&pool->queue_lock); + threadpool_job *job = ui_queue_get_wait(pool->queue); return job; } -void threadpool_run(UiThreadpool *pool, job_callback_f func, void *data) { - // TODO: handle errors - +void threadpool_run(UiThreadpool *pool, job_callback_f func, void *data) { threadpool_job *job = malloc(sizeof(threadpool_job)); job->callback = func; job->data = data; - - pthread_mutex_lock(&pool->queue_lock); - threadpool_enqueue_job(pool, job); - - int create_thread = 0; - int destroy_thread = 0; - int diff = pool->queue_len - pool->num_idle; - - //if(pool->queue_len == 1) { - pthread_cond_signal(&pool->available); - //} - - pthread_mutex_unlock(&pool->queue_lock); + ui_queue_put(pool->queue, job); } -void threadpool_enqueue_job(UiThreadpool *pool, threadpool_job *job) { - pool_queue_t *q = malloc(sizeof(pool_queue_t)); - q->job = job; - q->next = NULL; - - if(pool->queue == NULL) { - pool->queue = q; - } else { - pool_queue_t *last_elem = pool->queue; - while(last_elem->next != NULL) { - last_elem = last_elem->next; - } - last_elem->next = q; - } - pool->queue_len++; -} - - - - UiThreadpool* ui_threadpool_create(int nthreads) { @@ -202,6 +145,66 @@ threadpool_run(pool, ui_threadpool_job_func, job); } +/* --------------------------------- Queue --------------------------------- */ + +UiQueue* ui_queue_create(void) { + UiQueue *queue = calloc(1, sizeof(UiQueue)); + pthread_mutex_init(&queue->lock, NULL); + pthread_mutex_init(&queue->avlbl_lock, NULL); + pthread_cond_init(&queue->available, NULL); + return queue; +} + +void ui_queue_free(UiQueue *queue) { + // TODO +} + +void ui_queue_put(UiQueue *queue, void *data) { + // create queue element + UiQueueElm *elm = malloc(sizeof(UiQueueElm)); + elm->data = data; + elm->next = NULL; + + pthread_mutex_lock(&queue->lock); + + // put queue element at the end of the linked list + if(queue->elements) { + UiQueueElm *end = queue->elements; + while(end->next) { + end = end->next; + } + end->next = elm; + } else { + queue->elements = elm; + } + queue->length++; + + // signal new available data + pthread_cond_signal(&queue->available); + + pthread_mutex_unlock(&queue->lock); +} + +void* ui_queue_get_wait(UiQueue *queue) { + pthread_mutex_lock(&queue->lock); + + void *data = NULL; + while(data == NULL) { + if(queue->length == 0) { + pthread_cond_wait(&queue->available, &queue->lock); + continue; + } else { + UiQueueElm *q = queue->elements; + data = q->data; + queue->elements = q->next; + queue->length--; + free(q); + } + } + + pthread_mutex_unlock(&queue->lock); + return data; +} #endif
--- a/ui/common/threadpool.h Sat Dec 06 14:12:11 2025 +0100 +++ b/ui/common/threadpool.h Sat Dec 06 15:24:13 2025 +0100 @@ -39,6 +39,8 @@ extern "C" { #endif +typedef struct UiQueueElm UiQueueElm; +typedef struct UiQueue UiQueue; typedef struct UiJob { UiObject *obj; @@ -48,22 +50,30 @@ void *finish_data; } UiJob; +struct UiQueueElm { + void *data; + UiQueueElm *next; +}; + +struct UiQueue { + UiQueueElm *elements; + size_t length; + pthread_mutex_t lock; + pthread_mutex_t avlbl_lock; + pthread_cond_t available; +}; typedef struct _threadpool_job threadpool_job; typedef void*(*job_callback_f)(void *data); typedef struct _pool_queue pool_queue_t; struct UiThreadpool { - pthread_mutex_t queue_lock; - pthread_mutex_t avlbl_lock; - pthread_cond_t available; - pool_queue_t *queue; - uint32_t queue_len; - uint32_t num_idle; - int min_threads; - int max_threads; - pthread_t *threads; - int nthreads; + UiQueue *queue; + uint32_t num_idle; + int min_threads; + int max_threads; + pthread_t *threads; + int nthreads; }; struct _threadpool_job { @@ -82,7 +92,11 @@ void* threadpool_func(void *data); threadpool_job* threadpool_get_job(UiThreadpool *pool); void threadpool_run(UiThreadpool *pool, job_callback_f func, void *data); -void threadpool_enqueue_job(UiThreadpool *pool, threadpool_job *job); + +UiQueue* ui_queue_create(void); +void ui_queue_free(UiQueue *queue); +void ui_queue_put(UiQueue *queue, void *data); +void* ui_queue_get_wait(UiQueue *queue); #ifdef __cplusplus }
--- a/ui/server/toolkit.c Sat Dec 06 14:12:11 2025 +0100 +++ b/ui/server/toolkit.c Sat Dec 06 15:24:13 2025 +0100 @@ -33,4 +33,49 @@ #include "toolkit.h" +#include "../common/message.h" +#include "../common/threadpool.h" +static const char *ui_app_name; + +static UiMessageHandler *message_handler; + +static ui_callback onstartup; +static void *onstartupdata; + +static UiQueue *event_queue; + +void ui_init(const char *appname, int argc, char **argv) { + ui_app_name = appname; + + message_handler = uic_simple_msg_handler(STDIN_FILENO, STDOUT_FILENO, ui_server_message_received); +} + +const char* ui_appname() { + return ui_app_name; +} + +void ui_onstartup(ui_callback f, void *userdata) { + onstartup = f; + onstartupdata = userdata; +} + +void ui_add_styledata(const char *styledata, int len) { + // NOOP +} + + +void ui_server_message_received(cxstring msg) { + +} + +void ui_main(void) { + event_queue = ui_queue_create(); + UiServerEvent *event = NULL; + while((event = ui_queue_get_wait(event_queue)) != NULL) { + if(event->callback) { + event->callback(&event->event, event->userdata); + } + } + ui_queue_free(event_queue); +}
--- a/ui/server/toolkit.h Sat Dec 06 14:12:11 2025 +0100 +++ b/ui/server/toolkit.h Sat Dec 06 15:24:13 2025 +0100 @@ -34,10 +34,29 @@ #include "../common/context.h" #include "../common/object.h" +#include <cx/string.h> + #ifdef __cplusplus extern "C" { #endif + +typedef struct UiServerEvent UiServerEvent; +typedef struct UiServerEventData UiServerEventData; +typedef void(*ui_srvevent_func)(UiServerEventData *event, void *userdata); + +struct UiServerEventData { + UiObject *obj; + cxmutstr str; + int intvalue; +}; +struct UiServerEvent { + UiServerEventData event; + ui_srvevent_func callback; + void *userdata; +}; + +void ui_server_message_received(cxstring msg); #ifdef __cplusplus