From df131ea4f913fea43c266517a154caa08ff9b088 Mon Sep 17 00:00:00 2001 From: Florian Jung Date: Tue, 8 Feb 2011 15:55:59 +0100 Subject: Updated program files are now reloaded automatically --- synth/watch_files.cpp | 160 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 synth/watch_files.cpp (limited to 'synth/watch_files.cpp') diff --git a/synth/watch_files.cpp b/synth/watch_files.cpp new file mode 100644 index 0000000..ce80224 --- /dev/null +++ b/synth/watch_files.cpp @@ -0,0 +1,160 @@ +#include +#include +#include +#include + +#include "watch_files.h" +#include "util.h" +#include "globals.h" +#include "in_synth_cli.h" + +using namespace std; + +int fd=-1; +map > inotify_map; +pthread_mutex_t inotify_map_mutex; + +void watch_files_cleanup(void* unused) +{ + if (fd==-1) + { + output_verbose("NOTE: no cleaning necessary for watch-files-thread"); + } + else + { + output_verbose("NOTE: cleaning up for watch-files-thread..."); + + } +} + +void* watch_files(void* unused) +{ + pthread_cleanup_push(watch_files_cleanup, NULL); + + pthread_mutex_init(&inotify_map_mutex, NULL); + + fd=inotify_init(); + if (fd==-1) + { + output_warning("WARNING: could not initalize inotify. you must inform me about\n" + " updated files manually."); + while (true) sleep(10); + } + else + { + for (int i=0;i<128;i++) // add watches for all loaded programs + if (programfile[i]!="") + add_watch(i); + + inotify_event ev; + size_t s; + while (true) + { + s=read (fd, &ev, sizeof(inotify_event)); + while (s& tmp=inotify_map[ev.wd]; + for (set::iterator it=tmp.begin(); it!=tmp.end(); it++) + str+="#"+IntToStr(*it)+" "; + + output_verbose("NOTE: reloading programs "+str+"..."); + } + + set& tmp=inotify_map[ev.wd]; + for (set::iterator it=tmp.begin(); it!=tmp.end(); it++) + lock_and_load_program_no_watch_updates(*it, programfile[*it]); + } + else if (ev.mask & (IN_MOVE_SELF | IN_DELETE_SELF)) + { + if (verbose) + { + string str=""; + set& tmp=inotify_map[ev.wd]; + for (set::iterator it=tmp.begin(); it!=tmp.end(); it++) + str+="#"+IntToStr(*it)+" "; + + output_verbose("NOTE: removed watch for programs "+str); + } + + inotify_map.erase(ev.wd); + inotify_rm_watch(fd,ev.wd); + } + else if (ev.mask != IN_IGNORED) + { + output_note("NOTE: in watch_files-thread: unknown event received ("+IntToStrHex(ev.mask)+")"); + } + + pthread_mutex_unlock(&inotify_map_mutex); + } + } + + pthread_cleanup_pop(0); +} + +void remove_watch(int prog) +{ + if (watchfiles) + { + map >::iterator mit; + set* tmp; + set::iterator sit; + + pthread_mutex_lock(&inotify_map_mutex); + + //search in all known watch descriptors + for (mit=inotify_map.begin(); mit!=inotify_map.end(); mit++) + { + tmp=&(mit->second); + sit=tmp->find(prog); + + //search for some wd which affects $prog + if (sit!=tmp->end()) //found? + { + //erase $prog from the affect-set + tmp->erase(sit); + if (tmp->empty()) + { + //if the affect-set is now empty, we can garbage-collect + //the wd (i.e., remove it) + cout << "garbage collecting wd #"<first<first); + inotify_map.erase(mit); + } + + //we're done now + break; + } + } + + pthread_mutex_unlock(&inotify_map_mutex); + } +} + +void add_watch(int prog) +{ + if (watchfiles) + { + int wd=inotify_add_watch(fd, programfile[prog].c_str(), IN_MODIFY | IN_MOVE_SELF | IN_DELETE_SELF); + + pthread_mutex_lock(&inotify_map_mutex); + + if (wd!=-1) + { + inotify_map[wd].insert(prog); + } + else + { + //TODO: warning + } + + pthread_mutex_unlock(&inotify_map_mutex); + } +} -- cgit v1.2.3