static void check_event(FAMConnection * fc) { int ret; FAMEvent fe; ret = FAMPending(fc); if (ret < 0) { fprintf(stderr, "FAMPending() failed\n"); exit(1); } while (ret > 0) { ret = FAMNextEvent(fc, &fe); if (ret < 0) { fprintf(stderr, "FAMNextEvent() failed\n"); exit(1); } print_event(&fe); ret = FAMPending(fc); if (ret < 0) { fprintf(stderr, "FAMPending() failed\n"); exit(1); } } }
static int printEvents(int no) { int ret; ret = FAMPending(&(testState.fc)); if (ret < 0) { fprintf(stderr, "events line %d: FAMPending failed\n", no); return (-1); } if (ret == 0) { printf("no events\n"); } while (ret != 0) { ret = printEvent(no); if (ret < 0) return (-1); ret = FAMPending(&(testState.fc)); if (ret < 0) { fprintf(stderr, "events line %d: FAMPending failed\n", no); return (-1); } } return (0); }
static void viewer_fam_input(viewer_t *viewer, int fd, GdkInputCondition condition) { FAMEvent fe; while ( FAMPending(&(viewer->fc)) > 0 ) { if ( FAMNextEvent(&(viewer->fc), &fe) < 0 ) { fprintf(stderr, NAME ": WARNING: Failed to retrieve FAM event: %s\n", FamErrlist[FAMErrno]); fprintf(stderr, NAME ": WARNING: Disabling file update detection.\n"); viewer_fam_close(viewer); return; } switch ( fe.code ) { case FAMDeleted: case FAMMoved: viewer_clear(viewer); break; case FAMChanged: case FAMCreated: viewer_follow(viewer, 0); break; default: break; } } }
static void* fhs_event_process(void *data) { struct fe_handler *feh = (struct fe_handler*)data; FAMEvent fe; FAMRequest fr; FAMConnection fc; char* root_path; root_path = g_hash_table_lookup(feh->ohh->config, "root_path"); FAMOpen(&fc); FAMMonitorDirectory(&fc, root_path, &fr, REQ_RES); while(!feh->closing) { /* The old code is: FAMNextEvent(&fc, &fe); The new code is if (1 == FAMPending(&fc)) { FAMNextEvent(&fc, &fe); }else continue; In the old code, if this thread is processing FAMNextEvent and then feh->closing is set by another thread, this thread is still hung up. so the synchronized call is changed as asychronized call (polling call) though I don't like this mode. */ if (1 == FAMPending(&fc)) { FAMNextEvent(&fc, &fe); }else continue; if ((fe.userdata == REQ_RES) && ((fe.code == FAMCreated) || (fe.code == FAMExists))) { if (!IS_DIR(fe.filename)) fhs_event_add_resource(feh, fe.filename, &fe); }else if ((fe.userdata == REQ_RDR) && (fe.code == FAMDeleted)) { if (!IS_DIR(fe.filename)) fhs_event_remove_resource(feh, &fe); else printf("faint! why delete root path\n"); }else if (fe.userdata == REQ_RDR) { if (((fe.code == FAMChanged) || (fe.code == FAMExists))&& ((!strcmp(fe.filename, "reading"))|| (!strcmp(fe.filename, "thres")))) { fhs_event_sensor_update(feh, &fe); } } } FAMClose(&fc); return 0; }
static int debugLoop(int timeoutms) { fd_set read_set; struct timeval tv; int avail; int fd; if (interactive) debugPrompt(); retry: FD_ZERO(&read_set); FD_SET(0, &read_set); fd = 0; if (testState.connected) { FD_SET(testState.fc.fd, &read_set); fd = testState.fc.fd; } if (timeoutms >= 0) { tv.tv_sec = timeoutms / 1000; tv.tv_usec = (timeoutms % 1000) * 1000; avail = select(fd + 1, &read_set, NULL, NULL, &tv); if (avail == 0) return(0); } else { avail = select(fd + 1, &read_set, NULL, NULL, NULL); } if (avail < 0) { if (errno == EINTR) goto retry; fprintf(stderr, "debugLoop: select() failed \n"); return (-1); } if (testState.connected) { if (FD_ISSET(testState.fc.fd, &read_set)) { if (FAMPending(&(testState.fc)) > 0) { if (interactive) printf("\n"); printEvents(0); if (interactive) debugPrompt(); } } } if (timeoutms >= 0) return(0); if (!(FD_ISSET(0, &read_set))) goto retry; return(0); }
handler_t stat_cache_handle_fdevent(server *srv, void *_fce, int revent) { size_t i; stat_cache *sc = srv->stat_cache; size_t events; UNUSED(_fce); /* */ if (revent & FDEVENT_IN) { events = FAMPending(&sc->fam); for (i = 0; i < events; i++) { FAMEvent fe; fam_dir_entry *fam_dir; splay_tree *node; int ndx, j; FAMNextEvent(&sc->fam, &fe); /* handle event */ switch(fe.code) { case FAMChanged: case FAMDeleted: case FAMMoved: /* if the filename is a directory remove the entry */ fam_dir = fe.userdata; fam_dir->version++; /* file/dir is still here */ if (fe.code == FAMChanged) break; /* we have 2 versions, follow and no-follow-symlink */ for (j = 0; j < 2; j++) { buffer_copy_string(sc->hash_key, fe.filename); buffer_append_int(sc->hash_key, j); ndx = hashme(sc->hash_key); sc->dirs = splaytree_splay(sc->dirs, ndx); node = sc->dirs; if (node && (node->key == ndx)) { int osize = splaytree_size(sc->dirs); fam_dir_entry_free(&sc->fam, node->data); sc->dirs = splaytree_delete(sc->dirs, ndx); force_assert(osize - 1 == splaytree_size(sc->dirs)); } } break; default: break; } } } if (revent & FDEVENT_HUP) { /* fam closed the connection */ fdevent_event_del(srv->ev, &(sc->fam_fcce_ndx), FAMCONNECTION_GETFD(&sc->fam)); fdevent_unregister(srv->ev, FAMCONNECTION_GETFD(&sc->fam)); FAMClose(&sc->fam); } return HANDLER_GO_ON; }
/* event handler of all FAM events */ static gboolean on_fam_event( GIOChannel * channel, GIOCondition cond, gpointer user_data ) { #ifdef USE_INOTIFY /* Linux inootify */ #define BUF_LEN (1024 * (sizeof (struct inotify_event) + 16)) char buf[ BUF_LEN ]; int i, len; #else /* FAM|gamin */ FAMEvent evt; #endif VFSFileMonitor* monitor = NULL; if ( cond & (G_IO_HUP | G_IO_ERR) ) { disconnect_from_fam(); if ( g_hash_table_size ( monitor_hash ) > 0 ) { /* Disconnected from FAM server, but there are still monitors. This may be caused by crash of FAM server. So we have to reconnect to FAM server. */ connect_to_fam(); g_hash_table_foreach( monitor_hash, ( GHFunc ) reconnect_fam, NULL ); } return TRUE; /* don't need to remove the event source since it has been removed by disconnect_from_fam(). */ } #ifdef USE_INOTIFY /* Linux inotify */ while ( ( len = read ( inotify_fd, buf, BUF_LEN ) ) < 0 && errno == EINTR ); if ( len < 0 ) { g_warning ( "Error reading inotify event: %s", g_strerror ( errno ) ); /* goto error_cancel; */ return FALSE; } if ( len == 0 ) { /* * FIXME: handle this better? */ g_warning ( "Error reading inotify event: supplied buffer was too small" ); /* goto error_cancel; */ return FALSE; } i = 0; while ( i < len ) { struct inotify_event * ievent = ( struct inotify_event * ) & buf [ i ]; /* FIXME: 2 different paths can have the same wd because of link */ monitor = ( VFSFileMonitor* ) g_hash_table_find( monitor_hash, find_monitor, GINT_TO_POINTER( ievent->wd ) ); if( G_LIKELY(monitor) ) { const char* file_name; file_name = ievent->len > 0 ? ievent->name : monitor->path; /* //MOD for debug output only char* desc; if ( ievent->mask & ( IN_CREATE | IN_MOVED_TO ) ) desc = "CREATE"; else if ( ievent->mask & ( IN_DELETE | IN_MOVED_FROM | IN_DELETE_SELF | IN_UNMOUNT ) ) desc = "DELETE"; else if ( ievent->mask & ( IN_MODIFY | IN_ATTRIB ) ) desc = "CHANGE"; if ( !strcmp( monitor->path, "/tmp" ) && g_str_has_prefix( file_name, "vte" ) ) { } // due to current vte scroll problems creating and deleting massive numbers of // /tmp/vte8CBO7V types of files, ignore these (creates feedback loop when // spacefm is run in terminal because each printf triggers a scroll, // which triggers another printf below, which triggers another file change) // https://bugs.launchpad.net/ubuntu/+source/vte/+bug/778872 else printf("inotify-event %s: %s///%s\n", desc, monitor->path, file_name); //g_debug("inotify (%d) :%s", ievent->mask, file_name); */ dispatch_event( monitor, translate_inotify_event( ievent->mask ), file_name ); } i += sizeof ( struct inotify_event ) + ievent->len; } #else /* FAM|gamin */ while ( FAMPending( &fam ) ) { if ( FAMNextEvent( &fam, &evt ) > 0 ) { monitor = ( VFSFileMonitor* ) evt.userdata; switch ( evt.code ) { case FAMCreated: case FAMDeleted: case FAMChanged: /* FIXME: There exists a possibility that a file can accidentally become a directory, and a directory can become a file when using chmod. Should we delete original request, and create a new one when this happens? */ /* g_debug("FAM event(%d): %s", evt.code, evt.filename); */ /* Call the callback functions */ dispatch_event( monitor, evt.code, evt.filename ); break; /* Other events are not supported */ default: break; } } } #endif return TRUE; }
static int processCommand(char *line, int no) { int ret, args; char *command = NULL; char *arg = NULL; char *arg2 = NULL; if (line == NULL) return (-1); if (line[0] == '#') return (0); args = scanCommand(line, &command, &arg, &arg2); if (args < 0) return (-1); if (args == 0) return (0); if (!strcmp(command, "connect")) { if (testState.connected) { fprintf(stderr, "connect line %d: already connected\n", no); return (-1); } if (arg != NULL) { #ifdef HAVE_SETENV setenv("GAM_CLIENT_ID", arg, 1); #elif HAVE_PUTENV char *client_id = malloc (strlen (arg) + sizeof "GAM_CLIENT_ID="); if (client_id) { strcpy (client_id, "GAM_CLIENT_ID="); strcat (client_id, arg); putenv (client_id); } #endif /* HAVE_SETENV */ } ret = FAMOpen(&(testState.fc)); if (ret < 0) { fprintf(stderr, "connect line %d: failed to connect\n", no); return (-1); } testState.connected = 1; if (arg != NULL) printf("connected to %s\n", arg); else printf("connected\n"); } else if (!strcmp(command, "kill")) { /* * okay, it's heavy but that's the simplest way since we do not have * the pid(s) of the servers running. */ ret = system("killall gam_server"); if (ret < 0) { fprintf(stderr, "kill line %d: failed to killall gam_server\n", no); return (-1); } printf("killall gam_server\n"); } else if (!strcmp(command, "disconnect")) { if (testState.connected == 0) { fprintf(stderr, "disconnect line %d: not connected\n", no); return (-1); } ret = FAMClose(&(testState.fc)); if (ret < 0) { fprintf(stderr, "connect line %d: failed to disconnect\n", no); return (-1); } testState.connected = 0; printf("disconnected\n"); } else if (!strcmp(command, "mondir")) { if (args >= 2) { if (arg[0] != '/') snprintf(filename, sizeof(filename), "%s/%s", pwd, arg); else snprintf(filename, sizeof(filename), "%s", arg); } if (args == 2) { ret = FAMMonitorDirectory(&(testState.fc), filename, &(testState. fr[testState.nb_requests]), NULL); } else if (args == 3) { int index; if (sscanf(arg2, "%d", &index) <= 0) { fprintf(stderr, "mondir line %d: invalid index value %s\n", no, arg2); return (-1); } testState.fr[testState.nb_requests].reqnum = index; ret = FAMMonitorDirectory2(&(testState.fc), filename, &(testState. fr[testState.nb_requests])); } else { fprintf(stderr, "mondir line %d: invalid format\n", no); return (-1); } if (ret < 0) { fprintf(stderr, "mondir line %d: failed to monitor %s\n", no, arg); return (-1); } printf("mondir %s %d\n", arg, testState.nb_requests); testState.nb_requests++; } else if (!strcmp(command, "monfile")) { if (args != 2) { fprintf(stderr, "monfile line %d: lacks name\n", no); return (-1); } if (arg[0] != '/') snprintf(filename, sizeof(filename), "%s/%s", pwd, arg); else snprintf(filename, sizeof(filename), "%s", arg); ret = FAMMonitorFile(&(testState.fc), filename, &(testState.fr[testState.nb_requests]), NULL); if (ret < 0) { fprintf(stderr, "monfile line %d: failed to monitor %s\n", no, arg); return (-1); } printf("monfile %s %d\n", arg, testState.nb_requests); testState.nb_requests++; } else if (!strcmp(command, "pending")) { if (args != 1) { fprintf(stderr, "pending line %d: extra argument %s\n", no, arg); return (-1); } ret = FAMPending(&(testState.fc)); if (ret < 0) { fprintf(stderr, "pending line %d: failed\n", no); return (-1); } printf("pending %d\n", ret); } else if (!strcmp(command, "mkdir")) { if (args != 2) { fprintf(stderr, "mkdir line %d: lacks name\n", no); return (-1); } ret = mkdir(arg, 0755); if (ret < 0) { fprintf(stderr, "mkdir line %d: failed to create %s\n", no, arg); return (-1); } printf("mkdir %s\n", arg); } else if (!strcmp(command, "chmod")) { if (args != 3) { fprintf(stderr, "chmod line %d: lacks path and mode\n", no); return (-1); } ret = chmod(arg, strtol (arg2, NULL, 8)); if (ret < 0) { fprintf(stderr, "chmod line %d: failed to chmod %s to %s\n", no, arg, arg2); return (-1); } printf("chmod %s to %s\n", arg, arg2); } else if (!strcmp(command, "chown")) { if (args != 3) { fprintf(stderr, "chown line %d: lacks path and owner\n", no); return (-1); } struct stat sb; if (!lstat (arg, &sb)) { ret = (S_ISLNK (sb.st_mode)) ? lchown(arg, strtol(arg2, NULL, 10), -1) : chown(arg, strtol(arg2, NULL, 10), -1); } else ret=-1; if (ret < 0) { fprintf(stderr, "chown line %d: failed to chown %s to %s\n", no, arg, arg2); return (-1); } printf("chown %s to %s\n", arg, arg2); } else if (!strcmp(command, "mkfile")) { if (args != 2) { fprintf(stderr, "mkfile line %d: lacks name\n", no); return (-1); } ret = open(arg, O_CREAT | O_WRONLY, 0666); if (ret < 0) { fprintf(stderr, "mkfile line %d: failed to open %s\n", no, arg); return (-1); } close(ret); printf("mkfile %s\n", arg); } else if (!strcmp(command, "append")) { if (args != 2) { fprintf(stderr, "mkfile line %d: lacks name\n", no); return (-1); } ret = open(arg, O_RDWR | O_APPEND); if (ret < 0) { fprintf(stderr, "append line %d: failed to open %s\n", no, arg); return (-1); } write(ret, "a", 1); close(ret); printf("append %s\n", arg); } else if (!strcmp(command, "rmdir")) { if (args != 2) { fprintf(stderr, "rmdir line %d: lacks name\n", no); return (-1); } ret = rmdir(arg); if (ret < 0) { fprintf(stderr, "rmdir line %d: failed to remove %s\n", no, arg); return (-1); } printf("rmdir %s\n", arg); } else if (!strcmp(command, "rmfile")) { if (args != 2) { fprintf(stderr, "rmfile line %d: lacks name\n", no); return (-1); } ret = unlink(arg); if (ret < 0) { fprintf(stderr, "rmfile line %d: failed to unlink %s\n", no, arg); return (-1); } printf("rmfile %s\n", arg); } else if (!strcmp(command, "move")) { if (args != 3) { fprintf(stderr, "move line %d: lacks something\n", no); return (-1); } ret = rename(arg, arg2); if (ret < 0) { fprintf(stderr, "move line %d: failed to move %s\n", no, arg); return (-1); } printf("move %s %s\n", arg, arg2); } else if (!strcmp(command, "link")) { if (args != 3) { fprintf(stderr, "link line %d: lacks target and name\n", no); return (-1); } ret = symlink(arg, arg2); if (ret < 0) { fprintf(stderr, "link line %d: failed to link to %s\n", no, arg); return (-1); } printf("link %s to %s\n", arg2, arg); } else if (!strcmp(command, "event")) { printEvent(no); } else if (!strcmp(command, "events")) { printEvents(no); } else if (!strcmp(command, "expect")) { int count; int delay = 0; int nb_events = testState.nb_events; if (args != 2) { fprintf(stderr, "expect line %d: lacks number\n", no); return (-1); } if (sscanf(arg, "%d", &count) <= 0) { fprintf(stderr, "expect line %d: invalid number value %s\n", no, arg); return (-1); } /* * wait at most 3 secs before declaring failure */ while ((delay < 30) && (testState.nb_events < nb_events + count)) { debugLoop(100); /* printf("+"); fflush(stdout); */ delay++; } if (testState.nb_events < nb_events + count) { printf("expect line %d: got %d of %d expected events\n", no, testState.nb_events - nb_events, count); return (-1); } } else if (!strcmp(command, "sleep")) { int i; for (i = 0; (i < 30) && (FAMPending(&(testState.fc)) == 0); i++) usleep(50000); } else if (!strcmp(command, "wait")) { sleep(1); } else if (!strcmp(command, "cancel")) { if (args == 2) { int req_index = 0; if (sscanf(arg, "%d", &req_index) <= 0 || req_index >= testState.nb_requests) { fprintf(stderr, "cancel line %d: invalid req_index value %s\n", no, arg); return (-1); } ret = FAMCancelMonitor(&(testState.fc), &(testState.fr[req_index])); } else { fprintf(stderr, "cancel line %d: invalid format\n", no); return (-1); } if (ret < 0) { fprintf(stderr, "cancel line %d: failed to cancel req_index %s\n", no, arg); return (-1); } printf("cancel %s %d\n", arg, testState.nb_requests); } else { fprintf(stderr, "Unable to parse line %d: %s\n", no, line); return (-1); } return (0); }
static gboolean g_fam_file_monitor_callback (gint fd, GIOCondition condition, gpointer user_data) { gint64 now = g_source_get_time (fam_source); g_mutex_lock (&fam_lock); while (FAMPending (&fam_connection)) { const gchar *child; FAMEvent ev; if (FAMNextEvent (&fam_connection, &ev) != 1) { /* The daemon died. We're in a really bad situation now * because we potentially have a bunch of request structures * outstanding which no longer make any sense to anyone. * * The best thing that we can do is do nothing. Notification * won't work anymore for this process. */ g_mutex_unlock (&fam_lock); g_warning ("Lost connection to FAM (file monitoring) service. Expect no further file monitor events."); return FALSE; } /* We expect ev.filename to be a relative path for children in a * monitored directory, and an absolute path for a monitored file * or the directory itself. */ if (ev.filename[0] != '/') child = ev.filename; else child = NULL; switch (ev.code) { case FAMAcknowledge: g_source_unref (ev.userdata); break; case FAMChanged: g_file_monitor_source_handle_event (ev.userdata, G_FILE_MONITOR_EVENT_CHANGED, child, NULL, NULL, now); break; case FAMDeleted: g_file_monitor_source_handle_event (ev.userdata, G_FILE_MONITOR_EVENT_DELETED, child, NULL, NULL, now); break; case FAMCreated: g_file_monitor_source_handle_event (ev.userdata, G_FILE_MONITOR_EVENT_CREATED, child, NULL, NULL, now); break; default: /* unknown type */ break; } } g_mutex_unlock (&fam_lock); return TRUE; }
/** * Process all pending events. * Helper thread for the worker thread. Just there * to process FAM events. Puts all events into the * queue for the main worker. */ static void * processEvents(void * arg) { DIC * cls = arg; FAMEvent fe; fd_set r; fd_set w; fd_set e; int fd = cls->fc.fd; int i; cls->log(cls->logContext, DOODLE_LOG_VERY_VERBOSE, _("Event processing thread created.\n")); while ( (0 == testShutdown()) && (cls->continueRunning) ) { char * name; FD_ZERO(&r); FD_ZERO(&w); FD_ZERO(&e); FD_SET(fd, &r); i = select(fd+1, &r, &w, &e, NULL); if (i == -1) { if (errno == EINTR) continue; cls->log(cls->logContext, DOODLE_LOG_CRITICAL, _("Call to '%s' failed: %s\n"), "select", strerror(errno)); } if (!FD_ISSET(fd, &r)) continue; if (! FAMPending(&cls->fc)) { /* this should only happen if there was a problem with select, and in this case we better add some artificial delay (busy waiting) */ sleep(1); continue; } MUTEX_LOCK(&cls->lock); if (-1 == FAMNextEvent(&cls->fc, &fe)) { cls->log(cls->logContext, DOODLE_LOG_CRITICAL, _("Call to '%s' failed: %s\n"), "FAMNextEvent", FamErrlist[FAMErrno]); /* avoid fast, persistent errors */ sleep(1); continue; } name = malloc(strlen(fe.filename) + strlen((char*) fe.userdata) + 2); if (fe.filename[0] == '/') { strcpy(name, fe.filename); } else { strcpy(name, (char*) fe.userdata); if ( (strlen((char*)fe.userdata) > 0) && (((char*)fe.userdata)[strlen(fe.userdata)-1] != DIR_SEPARATOR) ) strcat(name, DIR_SEPARATOR_STR); strcat(name, fe.filename); } /* never process the doodle database itself... */ if (0 == strncmp(name, cls->ename, strlen(cls->ename))) { free(name); MUTEX_UNLOCK(&cls->lock); continue; } cls->log(cls->logContext, DOODLE_LOG_INSANELY_VERBOSE, "FAM EVENT (%d,%s,%s) on file '%s'.\n", fe.code, fe.userdata, fe.filename, name); switch (fe.code) { case FAMCreated: case FAMChanged: case FAMDeleted: case FAMMoved: case FAMAcknowledge: case FAMExists: case FAMEndExist: GROW(cls->events, cls->eventCount, cls->eventCount+1); cls->events[cls->eventCount-1] = strdup(name); SEMAPHORE_UP(cls->signal); break; default: break; } /* end switch */ free(name); MUTEX_UNLOCK(&cls->lock); } /* if event */ cls->continueRunning = 0; SEMAPHORE_UP(cls->signal); return NULL; }
int main(int argc, char **argv) { vector<string> cfg; size_t cfg_num = 0; if(argc==2) { cfg.push_back(argv[1]); } else if(argc==3) { cfg.push_back(argv[1]); cfg.push_back(argv[2]); } else { cfg.push_back(CONFIG_FILE); } time_t mtime; struct stat s; if (stat(cfg[cfg_num].c_str(), &s) == 0) { mtime = s.st_mtime; } else { mtime = 0; } cout << "BBC MDI Generator Rev " << svn_version() << ", using libsdixml Rev " << libsdixml::svn_version() << endl << "Implementing SDI Schema version " << libsdixml::SDI_Schema_version() << endl << "Reading config from " << cfg[cfg_num] << endl; cout.flush(); Mdigen mdigen; /* DcpIn dcpin; dcpin.ReConfigure("dcp.udp://:9998"); tagpacketlist t; dcpin.getFrame(t); for(tagpacketlist::iterator i=t.begin(); i!=t.end(); i++) cout << i->first << " " << i->second.size() << endl; */ #ifdef WIN32 int iResult; WSADATA wsaData; // Initialize Winsock iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { printf("WSAStartup failed: %d\n", iResult); exit(1); } #else struct sigaction sa; sa.sa_flags = SA_SIGINFO; sigemptyset(&sa.sa_mask); sa.sa_sigaction = signal_handler; if (sigaction(SIGHUP, &sa, NULL) == -1) { cerr << "error assigning signal handler" << endl; exit(1); } FAMConnection fc; if(FAMOpen(&fc)==0) { FAMRequest fr; if(cfg[0][0]!='/') { string path = getenv("PWD"); cerr << path << endl; cfg[0] = path + "/" + cfg[0]; } if(FAMMonitorFile(&fc, cfg[0].c_str(), &fr, NULL)) cerr << "can't monitor " << cfg[0] << endl; else cout << "FAM Monitoring " << cfg[0] << endl; } else { cerr << "can't connect to file alteration monitor " << endl; } #endif bool ok = true; int max_frames = -1; int reconf_interval = 32; int reconf = reconf_interval; ReConfigure(mdigen, cfg[cfg_num], ok, max_frames); while(ok) { try { mdigen.eachframe(); //cout << "Frame: " << mdigen.transmitted_frames << endl; #ifndef WIN32 while(FAMPending(&fc)) { FAMEvent fe; FAMNextEvent(&fc, &fe); switch(fe.code) { case FAMDeleted: break; case FAMChanged: cout << "file alteration monitor detected config change" << endl; reconfiguration_requested = true; break; case FAMCreated: case FAMExists: break; case FAMEndExist: cout << "FAM initialised " << fe.filename << endl; break; case FAMAcknowledge: cout << "FAM cancel acknowledged " << fe.filename << endl; break; case FAMStartExecuting: case FAMStopExecuting: case FAMMoved: cout << "unexpected fam event " << fe.code << " '" << fe.filename << "'" << endl; break; default: cout << "unknown fam event " << fe.code << " '" << fe.filename << "'" << endl; } } #endif } catch(char const* e) { cerr << e << endl; cerr.flush(); } if(reconfiguration_requested) { ReConfigure(mdigen, cfg[cfg_num], ok, max_frames); } if(cfg.size()>1) { reconf--; if(reconf==0) { cfg_num = 1 - cfg_num; ReConfigure(mdigen, cfg[cfg_num], ok, max_frames); reconf = reconf_interval; } } if(max_frames!=-1 && mdigen.transmitted_frames > max_frames) break; } }