libresman
diff src/resman.c @ 22:174ddb6bf92a
separated platform-specific filewatch code
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 12 Feb 2014 22:32:30 +0200 |
parents | fe0dbdfbe403 |
children | f8e5a1491275 |
line diff
1.1 --- a/src/resman.c Wed Feb 12 22:05:28 2014 +0200 1.2 +++ b/src/resman.c Wed Feb 12 22:32:30 2014 +0200 1.3 @@ -4,58 +4,9 @@ 1.4 #include <assert.h> 1.5 #include <pthread.h> 1.6 #include "resman.h" 1.7 +#include "resman_impl.h" 1.8 #include "dynarr.h" 1.9 -#include "rbtree.h" 1.10 -#include "threadpool.h" 1.11 - 1.12 -#ifdef __linux__ 1.13 -#include <unistd.h> 1.14 -#include <fcntl.h> 1.15 -#include <sys/inotify.h> 1.16 -#endif 1.17 - 1.18 -struct resource { 1.19 - int id; 1.20 - char *name; 1.21 - void *data; 1.22 - int result; /* last callback-reported success/fail code */ 1.23 - 1.24 - int done_pending; 1.25 - int delete_pending; 1.26 - pthread_mutex_t lock; 1.27 - 1.28 - int num_loads; /* number of loads up to now */ 1.29 - 1.30 - /* file change monitoring */ 1.31 -#ifdef __WIN32__ 1.32 - HANDLE nhandle; 1.33 -#endif 1.34 -#ifdef __linux__ 1.35 - int nfd; 1.36 -#endif 1.37 -}; 1.38 - 1.39 -struct resman { 1.40 - struct resource **res; 1.41 - struct thread_pool *tpool; 1.42 - 1.43 - pthread_mutex_t lock; /* global resman lock (for res array changes) */ 1.44 - 1.45 - resman_load_func load_func; 1.46 - resman_done_func done_func; 1.47 - resman_destroy_func destroy_func; 1.48 - 1.49 - void *load_func_cls; 1.50 - void *done_func_cls; 1.51 - void *destroy_func_cls; 1.52 - 1.53 - /* file change monitoring */ 1.54 - struct rbtree *nresmap; 1.55 - struct rbtree *modset; 1.56 -#ifdef __linux__ 1.57 - int inotify_fd; 1.58 -#endif 1.59 -}; 1.60 +#include "filewatch.h" 1.61 1.62 1.63 static int find_resource(struct resman *rman, const char *fname); 1.64 @@ -63,14 +14,6 @@ 1.65 static void remove_resource(struct resman *rman, int idx); 1.66 static void work_func(void *data, void *cls); 1.67 1.68 -/* file modification watching */ 1.69 -static int init_file_monitor(struct resman *rman); 1.70 -static void destroy_file_monitor(struct resman *rman); 1.71 -static int start_watch(struct resman *rman, struct resource *res); 1.72 -static void stop_watch(struct resman *rman, struct resource *res); 1.73 -static void check_watch(struct resman *rman); 1.74 -static void reload_modified(struct rbnode *node, void *cls); 1.75 - 1.76 1.77 struct resman *resman_create(void) 1.78 { 1.79 @@ -99,7 +42,7 @@ 1.80 num_threads = atoi(env); 1.81 } 1.82 1.83 - if(init_file_monitor(rman) == -1) { 1.84 + if(resman_init_file_monitor(rman) == -1) { 1.85 return -1; 1.86 } 1.87 1.88 @@ -133,7 +76,7 @@ 1.89 1.90 tpool_free(rman->tpool); 1.91 1.92 - destroy_file_monitor(rman); 1.93 + resman_destroy_file_monitor(rman); 1.94 1.95 pthread_mutex_destroy(&rman->lock); 1.96 } 1.97 @@ -196,7 +139,7 @@ 1.98 1.99 1.100 /* then check for modified files */ 1.101 - check_watch(rman); 1.102 + resman_check_watch(rman); 1.103 1.104 1.105 if(!rman->done_func) { 1.106 @@ -230,7 +173,7 @@ 1.107 } 1.108 res->num_loads++; 1.109 1.110 - start_watch(rman, res); /* start watching the file for modifications */ 1.111 + resman_start_watch(rman, res); /* start watching the file for modifications */ 1.112 pthread_mutex_unlock(&res->lock); 1.113 } 1.114 return 0; 1.115 @@ -336,7 +279,7 @@ 1.116 /* remove a resource and leave the pointer null to reuse the slot */ 1.117 static void remove_resource(struct resman *rman, int idx) 1.118 { 1.119 - stop_watch(rman, rman->res[idx]); 1.120 + resman_stop_watch(rman, rman->res[idx]); 1.121 1.122 if(rman->destroy_func) { 1.123 rman->destroy_func(idx, rman->destroy_func_cls); 1.124 @@ -371,7 +314,7 @@ 1.125 } else { 1.126 /* succeded, start a watch */ 1.127 if(res->nfd <= 0) { 1.128 - start_watch(rman, res); 1.129 + resman_start_watch(rman, res); 1.130 } 1.131 } 1.132 } else { 1.133 @@ -380,100 +323,3 @@ 1.134 } 1.135 pthread_mutex_unlock(&res->lock); 1.136 } 1.137 - 1.138 -static int init_file_monitor(struct resman *rman) 1.139 -{ 1.140 - int fd; 1.141 - 1.142 - if((fd = inotify_init()) == -1) { 1.143 - return -1; 1.144 - } 1.145 - /* set non-blocking flag, to allow polling by reading */ 1.146 - fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); 1.147 - rman->inotify_fd = fd; 1.148 - 1.149 - /* create the fd->resource map */ 1.150 - rman->nresmap = rb_create(RB_KEY_INT); 1.151 - /* create the modified set */ 1.152 - rman->modset = rb_create(RB_KEY_INT); 1.153 - return 0; 1.154 -} 1.155 - 1.156 -static void destroy_file_monitor(struct resman *rman) 1.157 -{ 1.158 - rb_free(rman->nresmap); 1.159 - rb_free(rman->modset); 1.160 - 1.161 - if(rman->inotify_fd >= 0) { 1.162 - close(rman->inotify_fd); 1.163 - rman->inotify_fd = -1; 1.164 - } 1.165 -} 1.166 - 1.167 -static int start_watch(struct resman *rman, struct resource *res) 1.168 -{ 1.169 - int fd; 1.170 - 1.171 - if((fd = inotify_add_watch(rman->inotify_fd, res->name, IN_MODIFY)) == -1) { 1.172 - return -1; 1.173 - } 1.174 - printf("started watching file \"%s\" for modification (fd %d)\n", res->name, fd); 1.175 - rb_inserti(rman->nresmap, fd, res); 1.176 - 1.177 - res->nfd = fd; 1.178 - return 0; 1.179 -} 1.180 - 1.181 -static void stop_watch(struct resman *rman, struct resource *res) 1.182 -{ 1.183 - if(res->nfd > 0) { 1.184 - rb_deletei(rman->nresmap, res->nfd); 1.185 - inotify_rm_watch(rman->inotify_fd, res->nfd); 1.186 - } 1.187 -} 1.188 - 1.189 -static void check_watch(struct resman *rman) 1.190 -{ 1.191 - char buf[512]; 1.192 - struct inotify_event *ev; 1.193 - int sz, evsize; 1.194 - 1.195 - while((sz = read(rman->inotify_fd, buf, sizeof buf)) > 0) { 1.196 - ev = (struct inotify_event*)buf; 1.197 - while(sz > 0) { 1.198 - if(ev->mask & IN_MODIFY) { 1.199 - /* add the file descriptor to the modified set */ 1.200 - rb_inserti(rman->modset, ev->wd, 0); 1.201 - } 1.202 - 1.203 - evsize = sizeof *ev + ev->len; 1.204 - sz -= evsize; 1.205 - ev += evsize; 1.206 - } 1.207 - } 1.208 - 1.209 - /* for each item in the modified set, start a new job to reload it */ 1.210 - rb_foreach(rman->modset, reload_modified, rman); 1.211 - rb_clear(rman->modset); 1.212 -} 1.213 - 1.214 -/* this is called for each item in the modified set (see above) */ 1.215 -static void reload_modified(struct rbnode *node, void *cls) 1.216 -{ 1.217 - int watch_fd; 1.218 - struct resource *res; 1.219 - struct resman *rman = cls; 1.220 - 1.221 - watch_fd = rb_node_keyi(node); 1.222 - 1.223 - if(!(res = rb_findi(rman->nresmap, watch_fd))) { 1.224 - fprintf(stderr, "%s: can't find resource for watch descriptor: %d\n", 1.225 - __FUNCTION__, watch_fd); 1.226 - return; 1.227 - } 1.228 - assert(watch_fd == res->nfd); 1.229 - 1.230 - printf("file \"%s\" modified (fd %d)\n", res->name, rb_node_keyi(node)); 1.231 - 1.232 - tpool_add_work(rman->tpool, res); 1.233 -}