X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=src%2Fcommon.c;h=4d9450bc8aedbad59ac8d42fe14bc096a6e3f28b;hb=4840de39cd6a8298680f53964df5f6b090a7324d;hp=538cdfac8d3464f2f175045613150334ee84261b;hpb=2cb45085e0189f08d5bc30f0953db2fb3cd011fd;p=monky diff --git a/src/common.c b/src/common.c index 538cdfa..4d9450b 100644 --- a/src/common.c +++ b/src/common.c @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "diskio.h" #include @@ -385,10 +386,13 @@ static struct update_cb { struct update_cb *next; void (*func)(void); pthread_t thread; + sem_t start_wait, end_wait; } update_cb_head = { .next = NULL, }; +static void *run_update_callback(void *) __attribute__((noreturn)); + /* Register an update callback. Don't allow duplicates, to minimise side * effects and overhead. */ void add_update_callback(void (*func)(void)) @@ -403,9 +407,16 @@ void add_update_callback(void (*func)(void)) return; uc = uc->next; } + uc->next = malloc(sizeof(struct update_cb)); - memset(uc->next, 0, sizeof(struct update_cb)); - uc->next->func = func; + uc = uc->next; + + memset(uc, 0, sizeof(struct update_cb)); + uc->func = func; + sem_init(&uc->start_wait, 0, 0); + sem_init(&uc->end_wait, 0, 0); + + pthread_create(&uc->thread, NULL, &run_update_callback, uc); } /* Free the list element uc and all decendants recursively. */ @@ -413,6 +424,16 @@ static void __free_update_callbacks(struct update_cb *uc) { if (uc->next) __free_update_callbacks(uc->next); + + /* send cancellation request, then trigger and join the thread */ + pthread_cancel(uc->thread); + sem_post(&uc->start_wait); + pthread_join(uc->thread, NULL); + + /* finally destroy the semaphores */ + sem_destroy(&uc->start_wait); + sem_destroy(&uc->end_wait); + free(uc); } @@ -424,14 +445,15 @@ void free_update_callbacks(void) update_cb_head.next = NULL; } -static void *run_update_callback(void *) __attribute__((noreturn)); - static void *run_update_callback(void *data) { struct update_cb *ucb = data; - (*ucb->func)(); - pthread_exit(NULL); + while (1) { + sem_wait(&ucb->start_wait); + (*ucb->func)(); + sem_post(&ucb->end_wait); + } } int no_buffers; @@ -457,13 +479,12 @@ void update_stuff(void) prepare_update(); - for (uc = update_cb_head.next; uc; uc = uc->next) { - pthread_create(&uc->thread, NULL, &run_update_callback, uc); - } + for (uc = update_cb_head.next; uc; uc = uc->next) + sem_post(&uc->start_wait); /* need to synchronise here, otherwise locking is needed (as data * would be printed with some update callbacks still running) */ for (uc = update_cb_head.next; uc; uc = uc->next) - pthread_join(uc->thread, NULL); + sem_wait(&uc->end_wait); /* XXX: move the following into the update_meminfo() functions? */ if (no_buffers) {