# HG changeset patch # User John Tsiombikas # Date 1391558509 -7200 # Node ID 4d18498a007899f4a127b147b4f53a03fc79e9d4 # Parent 03f3de659c3225a102690be38444235510984288 moved the resource manager a bit further diff -r 03f3de659c32 -r 4d18498a0078 src/resman.c --- a/src/resman.c Tue Feb 04 05:42:31 2014 +0200 +++ b/src/resman.c Wed Feb 05 02:01:49 2014 +0200 @@ -2,6 +2,7 @@ #include #include #include +#include #include "resman.h" #include "dynarr.h" #include "threadpool.h" @@ -9,25 +10,29 @@ struct resource { char *name; void *data; + int result; /* last callback-reported success/fail code */ + + int done_pending; + pthread_mutex_t done_lock; }; struct resman { struct resource *res; + struct thread_pool *tpool; resman_load_func load_func; - resman_create_func create_func; - resman_update_func update_func; + resman_done_func done_func; resman_destroy_func destroy_func; void *load_func_cls; - void *create_func_cls; - void *update_func_cls; + void *done_func_cls; void *destroy_func_cls; }; static int find_resource(struct resman *rman, const char *fname); static int add_resource(struct resman *rman, const char *fname, void *data); +static void work_func(void *data, void *cls); struct resman *resman_create(void) { @@ -49,7 +54,13 @@ { memset(rman, 0, sizeof *rman); + if(!(rman->tpool = tpool_create(TPOOL_AUTO))) { + return -1; + } + tpool_set_work_func(rman->tpool, work_func, rman); + if(!(rman->res = dynarr_alloc(0, sizeof *rman->res))) { + tpool_free(rman->tpool); return -1; } @@ -67,6 +78,8 @@ } } dynarr_free(rman->res); + + tpool_free(rman->tpool); } @@ -76,16 +89,10 @@ rman->load_func_cls = cls; } -void resman_set_create_func(struct resman *rman, resman_create_func func, void *cls) +void resman_set_done_func(struct resman *rman, resman_done_func func, void *cls) { - rman->create_func = func; - rman->create_func_cls = cls; -} - -void resman_set_update_func(struct resman *rman, resman_update_func func, void *cls) -{ - rman->update_func = func; - rman->update_func_cls = cls; + rman->done_func = func; + rman->done_func_cls = cls; } void resman_set_destroy_func(struct resman *rman, resman_destroy_func func, void *cls) @@ -113,7 +120,30 @@ int resman_poll(struct resman *rman) { - /* TODO */ + int i, num_res; + + if(!rman->done_func) { + return 0; /* no done callback; there's no point in checking anything */ + } + + num_res = dynarr_size(rman->res); + for(i=0; ires + i; + int last_result; + + pthread_mutex_lock(&res->done_lock); + if(!res->done_pending) { + pthread_mutex_unlock(&res->done_lock); + continue; + } + + /* so a done callback *is* pending... */ + res->done_pending = 0; + last_result = res->result; + pthread_mutex_unlock(&res->done_lock); + + rman->done_func(last_result, res->data, rman->done_func_cls); + } return 0; } @@ -133,6 +163,14 @@ return 0; } +int resman_get_res_error(struct resman *rman, int res_id) +{ + if(res_id >= 0 && res_id < dynarr_size(rman->res)) { + return rman->res[res_id].result; + } + return -1; +} + static int find_resource(struct resman *rman, const char *fname) { int i, sz = dynarr_size(rman->res); @@ -160,7 +198,22 @@ rman->res[idx].data = data; - /* TODO start a loading job ... */ + /* start a loading job ... */ + tpool_add_work(rman->tpool, rman->res + idx); return idx; } + +/* this is the background work function which handles all the + * first-stage resource loading... + */ +static void work_func(void *data, void *cls) +{ + struct resource *res = data; + struct resman *rman = cls; + + res->result = rman->load_func(res->name, res->data, rman->load_func_cls); + pthread_mutex_lock(&res->done_lock); + res->done_pending = 1; + pthread_mutex_unlock(&res->done_lock); +} diff -r 03f3de659c32 -r 4d18498a0078 src/resman.h --- a/src/resman.h Tue Feb 04 05:42:31 2014 +0200 +++ b/src/resman.h Wed Feb 05 02:01:49 2014 +0200 @@ -2,12 +2,11 @@ #define RESOURCE_MANAGER_H_ /* load callback: everything or just file read/parse stage - * create callback: second-stage callback for first creation - * update callback: second-stage callback for reload + * done callback: second-stage callback, called in the context of the + * user thread, after the load callback returns */ typedef int (*resman_load_func)(const char *fname, void *data, void *closure); -typedef int (*resman_create_func)(void *data, void *closure); -typedef int (*resman_update_func)(void *data, void *closure); +typedef int (*resman_done_func)(int result, void *data, void *closure); typedef void (*resman_destroy_func)(void *data, void *closure); struct resman; @@ -23,8 +22,7 @@ void resman_destroy(struct resman *rman); void resman_set_load_func(struct resman *rman, resman_load_func func, void *cls); -void resman_set_create_func(struct resman *rman, resman_create_func func, void *cls); -void resman_set_update_func(struct resman *rman, resman_update_func func, void *cls); +void resman_set_done_func(struct resman *rman, resman_done_func func, void *cls); void resman_set_destroy_func(struct resman *rman, resman_destroy_func func, void *cls); int resman_lookup(struct resman *rman, const char *fname, void *data); @@ -35,6 +33,8 @@ void resman_set_res_data(struct resman *rman, int res_id, void *data); void *resman_get_res_data(struct resman *rman, int res_id); +int resman_get_res_error(struct resman *rman, int res_id); + #ifdef __cplusplus } #endif diff -r 03f3de659c32 -r 4d18498a0078 src/threadpool.c --- a/src/threadpool.c Tue Feb 04 05:42:31 2014 +0200 +++ b/src/threadpool.c Wed Feb 05 02:01:49 2014 +0200 @@ -69,6 +69,27 @@ pthread_cond_destroy(&tpool->work_cond); } +struct thread_pool *tpool_create(int num_threads) +{ + struct thread_pool *tpool = malloc(sizeof *tpool); + if(!tpool) { + return 0; + } + if(tpool_init(tpool, num_threads) == -1) { + free(tpool); + return 0; + } + return tpool; +} + +void tpool_free(struct thread_pool *tpool) +{ + if(tpool) { + tpool_destroy(tpool); + free(tpool); + } +} + void tpool_set_work_func(struct thread_pool *tpool, tpool_work_func func, void *cls) { tpool->work_func = func; diff -r 03f3de659c32 -r 4d18498a0078 src/threadpool.h --- a/src/threadpool.h Tue Feb 04 05:42:31 2014 +0200 +++ b/src/threadpool.h Wed Feb 05 02:01:49 2014 +0200 @@ -9,6 +9,9 @@ int tpool_init(struct thread_pool *tpool, int num_threads); void tpool_destroy(struct thread_pool *tpool); +struct thread_pool *tpool_create(int num_threads); +void tpool_free(struct thread_pool *tpool); + void tpool_set_work_func(struct thread_pool *tpool, tpool_work_func func, void *cls); int tpool_add_work(struct thread_pool *tpool, void *data);