Пример #1
0
  void kqueue_monitor::run()
  {
    initialize_kqueue();

    for(;;)
    {
#ifdef HAVE_CXX_MUTEX
      unique_lock<mutex> run_guard(run_mutex);
      if (should_stop) break;
      run_guard.unlock();
#endif

      // remove the deleted descriptors
      remove_deleted();

      // rescan the pending descriptors
      rescan_pending();

      // scan the root paths to check whether someone is missing
      scan_root_paths();

      vector<struct kevent> changes;
      vector<struct kevent> event_list;

      for (const pair<int, string>& fd_path : load->file_names_by_descriptor)
      {
        struct kevent change;

        EV_SET(&change,
               fd_path.first,
               EVFILT_VNODE,
               EV_ADD | EV_ENABLE | EV_CLEAR,
               NOTE_DELETE | NOTE_EXTEND | NOTE_RENAME | NOTE_WRITE | NOTE_ATTRIB | NOTE_LINK | NOTE_REVOKE,
               0,
               0);

        changes.push_back(change);
        struct kevent event;
        event_list.push_back(event);
      }

      /*
       * If no files can be observed yet, then wait and repeat the loop.
       */
      if (!changes.size())
      {
        sleep(latency);
        continue;
      }

      const int event_num = wait_for_events(changes, event_list);
      process_events(changes, event_list, event_num);
    }

    terminate_kqueue();
  }
Пример #2
0
  void inotify_monitor::run()
  {
    char buffer[BUFFER_SIZE];

    while (true)
    {
      process_pending_events();

      scan_root_paths();

      // If no files can be watched, sleep and repeat the loop.
      if (!impl->watched_descriptors.size())
      {
        sleep(latency);
        continue;
      }

      // Use select to timeout on file descriptor read the amount specified by
      // the monitor latency.  This way, the monitor has a chance to update its
      // watches with at least the periodicity expected by the user.
      fd_set set;
      struct timeval timeout;

      FD_ZERO(&set);
      FD_SET(impl->inotify_monitor_handle, &set);
      double sec;
      double frac = modf(this->latency, &sec);
      timeout.tv_sec = sec;
      timeout.tv_usec = 1000 * 1000 * frac;

      int rv = select(impl->inotify_monitor_handle + 1,
                      &set,
                      nullptr,
                      nullptr,
                      &timeout);

      if (rv == -1)
      {
        throw libfsw_exception(_("::select() on inotify descriptor encountered an error."));
      }

      // In case of read timeout just repeat the loop.
      if (rv == 0)
      {
        continue;
      }

      ssize_t record_num = read(impl->inotify_monitor_handle,
                                buffer,
                                BUFFER_SIZE);

      {
        ostringstream log;
        log << _("Number of records: ") << record_num << "\n";
        FSW_ELOG(log.str().c_str());
      }

      if (!record_num)
      {
        throw libfsw_exception(_("read() on inotify descriptor read 0 records."));
      }

      if (record_num == -1)
      {
        perror("read()");
        throw libfsw_exception(_("read() on inotify descriptor returned -1."));
      }

      time(&impl->curr_time);

      for (char *p = buffer; p < buffer + record_num;)
      {
        struct inotify_event * event = reinterpret_cast<struct inotify_event *> (p);

        preprocess_event(event);

        p += (sizeof (struct inotify_event)) + event->len;
      }

      if (impl->events.size())
      {
        notify_events(impl->events);

        impl->events.clear();
      }

      sleep(latency);
    }
  }