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(); }
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); } }