libresman
diff src/resman.c @ 10:4d18498a0078
moved the resource manager a bit further
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 05 Feb 2014 02:01:49 +0200 |
parents | bd9b4ff19c93 |
children | bebc065a941f |
line diff
1.1 --- a/src/resman.c Tue Feb 04 05:42:31 2014 +0200 1.2 +++ b/src/resman.c Wed Feb 05 02:01:49 2014 +0200 1.3 @@ -2,6 +2,7 @@ 1.4 #include <stdlib.h> 1.5 #include <string.h> 1.6 #include <assert.h> 1.7 +#include <pthread.h> 1.8 #include "resman.h" 1.9 #include "dynarr.h" 1.10 #include "threadpool.h" 1.11 @@ -9,25 +10,29 @@ 1.12 struct resource { 1.13 char *name; 1.14 void *data; 1.15 + int result; /* last callback-reported success/fail code */ 1.16 + 1.17 + int done_pending; 1.18 + pthread_mutex_t done_lock; 1.19 }; 1.20 1.21 struct resman { 1.22 struct resource *res; 1.23 + struct thread_pool *tpool; 1.24 1.25 resman_load_func load_func; 1.26 - resman_create_func create_func; 1.27 - resman_update_func update_func; 1.28 + resman_done_func done_func; 1.29 resman_destroy_func destroy_func; 1.30 1.31 void *load_func_cls; 1.32 - void *create_func_cls; 1.33 - void *update_func_cls; 1.34 + void *done_func_cls; 1.35 void *destroy_func_cls; 1.36 }; 1.37 1.38 1.39 static int find_resource(struct resman *rman, const char *fname); 1.40 static int add_resource(struct resman *rman, const char *fname, void *data); 1.41 +static void work_func(void *data, void *cls); 1.42 1.43 struct resman *resman_create(void) 1.44 { 1.45 @@ -49,7 +54,13 @@ 1.46 { 1.47 memset(rman, 0, sizeof *rman); 1.48 1.49 + if(!(rman->tpool = tpool_create(TPOOL_AUTO))) { 1.50 + return -1; 1.51 + } 1.52 + tpool_set_work_func(rman->tpool, work_func, rman); 1.53 + 1.54 if(!(rman->res = dynarr_alloc(0, sizeof *rman->res))) { 1.55 + tpool_free(rman->tpool); 1.56 return -1; 1.57 } 1.58 1.59 @@ -67,6 +78,8 @@ 1.60 } 1.61 } 1.62 dynarr_free(rman->res); 1.63 + 1.64 + tpool_free(rman->tpool); 1.65 } 1.66 1.67 1.68 @@ -76,16 +89,10 @@ 1.69 rman->load_func_cls = cls; 1.70 } 1.71 1.72 -void resman_set_create_func(struct resman *rman, resman_create_func func, void *cls) 1.73 +void resman_set_done_func(struct resman *rman, resman_done_func func, void *cls) 1.74 { 1.75 - rman->create_func = func; 1.76 - rman->create_func_cls = cls; 1.77 -} 1.78 - 1.79 -void resman_set_update_func(struct resman *rman, resman_update_func func, void *cls) 1.80 -{ 1.81 - rman->update_func = func; 1.82 - rman->update_func_cls = cls; 1.83 + rman->done_func = func; 1.84 + rman->done_func_cls = cls; 1.85 } 1.86 1.87 void resman_set_destroy_func(struct resman *rman, resman_destroy_func func, void *cls) 1.88 @@ -113,7 +120,30 @@ 1.89 1.90 int resman_poll(struct resman *rman) 1.91 { 1.92 - /* TODO */ 1.93 + int i, num_res; 1.94 + 1.95 + if(!rman->done_func) { 1.96 + return 0; /* no done callback; there's no point in checking anything */ 1.97 + } 1.98 + 1.99 + num_res = dynarr_size(rman->res); 1.100 + for(i=0; i<num_res; i++) { 1.101 + struct resource *res = rman->res + i; 1.102 + int last_result; 1.103 + 1.104 + pthread_mutex_lock(&res->done_lock); 1.105 + if(!res->done_pending) { 1.106 + pthread_mutex_unlock(&res->done_lock); 1.107 + continue; 1.108 + } 1.109 + 1.110 + /* so a done callback *is* pending... */ 1.111 + res->done_pending = 0; 1.112 + last_result = res->result; 1.113 + pthread_mutex_unlock(&res->done_lock); 1.114 + 1.115 + rman->done_func(last_result, res->data, rman->done_func_cls); 1.116 + } 1.117 return 0; 1.118 } 1.119 1.120 @@ -133,6 +163,14 @@ 1.121 return 0; 1.122 } 1.123 1.124 +int resman_get_res_error(struct resman *rman, int res_id) 1.125 +{ 1.126 + if(res_id >= 0 && res_id < dynarr_size(rman->res)) { 1.127 + return rman->res[res_id].result; 1.128 + } 1.129 + return -1; 1.130 +} 1.131 + 1.132 static int find_resource(struct resman *rman, const char *fname) 1.133 { 1.134 int i, sz = dynarr_size(rman->res); 1.135 @@ -160,7 +198,22 @@ 1.136 1.137 rman->res[idx].data = data; 1.138 1.139 - /* TODO start a loading job ... */ 1.140 + /* start a loading job ... */ 1.141 + tpool_add_work(rman->tpool, rman->res + idx); 1.142 1.143 return idx; 1.144 } 1.145 + 1.146 +/* this is the background work function which handles all the 1.147 + * first-stage resource loading... 1.148 + */ 1.149 +static void work_func(void *data, void *cls) 1.150 +{ 1.151 + struct resource *res = data; 1.152 + struct resman *rman = cls; 1.153 + 1.154 + res->result = rman->load_func(res->name, res->data, rman->load_func_cls); 1.155 + pthread_mutex_lock(&res->done_lock); 1.156 + res->done_pending = 1; 1.157 + pthread_mutex_unlock(&res->done_lock); 1.158 +}