Пример #1
0
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);
        }
    }
}
Пример #2
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;
    }
  }
}
Пример #3
0
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;
}
Пример #4
0
gboolean
ves_icall_System_IO_FAMW_InternalFAMNextEvent (gpointer conn,
					       MonoString **filename,
					       gint *code,
					       gint *reqnum)
{
	FAMEvent ev;

	if (FAMNextEvent (conn, &ev) == 1) {
		*filename = mono_string_new (mono_domain_get (), ev.filename);
		*code = ev.code;
		*reqnum = ev.fr.reqnum;
		return TRUE;
	}

	return FALSE;
}
Пример #5
0
static void* fhs_event_process(void *data)
{
        struct fe_handler *feh = (struct fe_handler*)data;
        FAMEvent fe;
        FAMRequest fr;
        FAMConnection fc;
        char*  root_path;

#ifndef UNIT_TEST 
        root_path = g_hash_table_lookup(feh->ohh->config, "root_path");
#else
        root_path = "/home/guorj/HPI/openhpi/src/plugins/simulator/test/resources";
#endif

        FAMOpen(&fc);
        FAMMonitorDirectory(&fc, root_path, &fr, (void*)req_res);

        while(!feh->done) {   

                FAMNextEvent(&fc, &fe);
                if ((fe.userdata == (void *)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 == (void*) req_res) && (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 == (void *)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);
#if 0
        free all resource id and rdr id;
#endif
        return 0;
}
Пример #6
0
static int
printEvent(int no)
{
    int ret;
    FAMEvent fe;
    char *data;

    ret = FAMNextEvent(&(testState.fc), &fe);
    if (ret < 0) {
        fprintf(stderr, "event(s) line %d: FAMNextEvent failed\n", no);
        return (-1);
    }
    testState.nb_events++;
    
    if (fe.userdata == NULL)
        data = "NULL";
    else
        data = fe.userdata;
    printf("%d: %s %s: %s\n",
           fe.fr.reqnum, fe.filename, codeName(fe.code), data);
    return (0);
}
Пример #7
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;
}
Пример #8
0
/* 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;
}
Пример #9
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;
}
Пример #10
0
/**
 * 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;
}
-    failwith("No file descriptors in pseudo-FAM");
+    caml_failwith("No file descriptors in pseudo-FAM");
     return Val_unit;
 #endif /* FAM_INOTIFY */
 #else /* FAM_PSEUDO */
@@ -209,7 +209,7 @@ value om_notify_monitor_directory(value 
 #ifdef WIN32
         CheckCode("om_notify_monitor_directory", FAMMonitorDirectoryTree(fc, name, &request, 0));
 #else /* WIN32 */
-        failwith("om_notify_monitor_directory: recursive monitoring is not allowed");
+        caml_failwith("om_notify_monitor_directory: recursive monitoring is not allowed");
 #endif /* !WIN32 */
     }
     else
@@ -294,13 +294,13 @@ value om_notify_next_event(value v_fc)
     CheckCode("om_notify_next_event", FAMNextEvent(fc, &event));
     code = event.code;
     if(code < 1 || code > 10)
-        failwith("om_notify_next_event: code out of bounds");
+        caml_failwith("om_notify_next_event: code out of bounds");
 
     /* Allocate the string name */
-    v_name = copy_string(event.filename);
+    v_name = caml_copy_string(event.filename);
 
     /* Allocate the tuple */
-    v_tuple = alloc_tuple(3);
+    v_tuple = caml_alloc_tuple(3);
     Field(v_tuple, 0) = Val_int(event.fr.reqnum);
     Field(v_tuple, 1) = v_name;
     Field(v_tuple, 2) = Val_int(code - 1);
Пример #12
0
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;
  }
}