libresman
diff src/filewatch_win32.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 | |
children | f8e5a1491275 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/filewatch_win32.c Wed Feb 12 22:32:30 2014 +0200 1.3 @@ -0,0 +1,113 @@ 1.4 +/* file modification monitoring for windows */ 1.5 +#ifdef WIN32 1.6 +#include <stdio.h> 1.7 +#include <assert.h> 1.8 +#include <unistd.h> 1.9 +#include <fcntl.h> 1.10 +#include <sys/inotify.h> 1.11 +#include "filewatch.h" 1.12 +#include "resman.h" 1.13 +#include "resman_impl.h" 1.14 + 1.15 +static void reload_modified(struct rbnode *node, void *cls); 1.16 + 1.17 +int resman_init_file_monitor(struct resman *rman) 1.18 +{ 1.19 + int fd; 1.20 + 1.21 + if((fd = inotify_init()) == -1) { 1.22 + return -1; 1.23 + } 1.24 + /* set non-blocking flag, to allow polling by reading */ 1.25 + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); 1.26 + rman->inotify_fd = fd; 1.27 + 1.28 + /* create the fd->resource map */ 1.29 + rman->nresmap = rb_create(RB_KEY_INT); 1.30 + /* create the modified set */ 1.31 + rman->modset = rb_create(RB_KEY_INT); 1.32 + return 0; 1.33 +} 1.34 + 1.35 +void resman_destroy_file_monitor(struct resman *rman) 1.36 +{ 1.37 + rb_free(rman->nresmap); 1.38 + rb_free(rman->modset); 1.39 + 1.40 + if(rman->inotify_fd >= 0) { 1.41 + close(rman->inotify_fd); 1.42 + rman->inotify_fd = -1; 1.43 + } 1.44 +} 1.45 + 1.46 +int resman_start_watch(struct resman *rman, struct resource *res) 1.47 +{ 1.48 + int fd; 1.49 + 1.50 + if((fd = inotify_add_watch(rman->inotify_fd, res->name, IN_MODIFY)) == -1) { 1.51 + return -1; 1.52 + } 1.53 + printf("started watching file \"%s\" for modification (fd %d)\n", res->name, fd); 1.54 + rb_inserti(rman->nresmap, fd, res); 1.55 + 1.56 + res->nfd = fd; 1.57 + return 0; 1.58 +} 1.59 + 1.60 +void resman_stop_watch(struct resman *rman, struct resource *res) 1.61 +{ 1.62 + if(res->nfd > 0) { 1.63 + rb_deletei(rman->nresmap, res->nfd); 1.64 + inotify_rm_watch(rman->inotify_fd, res->nfd); 1.65 + } 1.66 +} 1.67 + 1.68 +void resman_check_watch(struct resman *rman) 1.69 +{ 1.70 + char buf[512]; 1.71 + struct inotify_event *ev; 1.72 + int sz, evsize; 1.73 + 1.74 + while((sz = read(rman->inotify_fd, buf, sizeof buf)) > 0) { 1.75 + ev = (struct inotify_event*)buf; 1.76 + while(sz > 0) { 1.77 + if(ev->mask & IN_MODIFY) { 1.78 + /* add the file descriptor to the modified set */ 1.79 + rb_inserti(rman->modset, ev->wd, 0); 1.80 + } 1.81 + 1.82 + evsize = sizeof *ev + ev->len; 1.83 + sz -= evsize; 1.84 + ev += evsize; 1.85 + } 1.86 + } 1.87 + 1.88 + /* for each item in the modified set, start a new job to reload it */ 1.89 + rb_foreach(rman->modset, reload_modified, rman); 1.90 + rb_clear(rman->modset); 1.91 +} 1.92 + 1.93 +/* this is called for each item in the modified set (see above) */ 1.94 +static void reload_modified(struct rbnode *node, void *cls) 1.95 +{ 1.96 + int watch_fd; 1.97 + struct resource *res; 1.98 + struct resman *rman = cls; 1.99 + 1.100 + watch_fd = rb_node_keyi(node); 1.101 + 1.102 + if(!(res = rb_findi(rman->nresmap, watch_fd))) { 1.103 + fprintf(stderr, "%s: can't find resource for watch descriptor: %d\n", 1.104 + __FUNCTION__, watch_fd); 1.105 + return; 1.106 + } 1.107 + assert(watch_fd == res->nfd); 1.108 + 1.109 + printf("file \"%s\" modified (fd %d)\n", res->name, rb_node_keyi(node)); 1.110 + 1.111 + tpool_add_work(rman->tpool, res); 1.112 +} 1.113 + 1.114 +#else 1.115 +int resman_filewatch_win32_silence_empty_file_warning; 1.116 +#endif /* WIN32 */