/** * _kh_cancel_sub: * @sub a #kqueue_sub * * Stops monitoring on a subscription. * * Returns: %TRUE **/ gboolean _kh_cancel_sub (kqueue_sub *sub) { gboolean removed = FALSE; g_assert (kqueue_socket_pair[0] != -1); g_assert (sub != NULL); _km_remove (sub); G_LOCK (hash_lock); removed = g_hash_table_remove (subs_hash_table, GINT_TO_POINTER (sub->fd)); G_UNLOCK (hash_lock); if (removed) { /* fd will be closed in the kqueue thread */ _kqueue_thread_remove_fd (sub->fd); /* Bump the kqueue thread. It will pick up a new sub entry to remove*/ if (!_ku_write (kqueue_socket_pair[0], "R", 1)) KH_W ("Failed to bump the kqueue thread (remove fd, error %d)", errno); } return TRUE; }
/** * _kh_cancel_sub: * @sub a #kqueue_sub * * Stops monitoring on a subscription. * * Returns: %TRUE **/ gboolean _kh_cancel_sub (kqueue_sub *sub) { gboolean missing = FALSE; g_assert (kqueue_socket_pair[0] != -1); g_assert (sub != NULL); G_LOCK (hash_lock); missing = !g_hash_table_remove (subs_hash_table, GINT_TO_POINTER (sub->fd)); G_UNLOCK (hash_lock); if (missing) { /* If there were no fd for this subscription, file is still * missing. */ KH_W ("Removing subscription from missing"); _km_remove (sub); } else { /* fd will be closed in the kqueue thread */ _kqueue_thread_remove_fd (sub->fd); /* Bump the kqueue thread. It will pick up a new sub entry to remove*/ if (!_ku_write (kqueue_socket_pair[0], "R", 1)) KH_W ("Failed to bump the kqueue thread (remove fd, error %d)", errno); } return TRUE; }
/** * _kh_start_watching: * @sub: a #kqueue_sub * * Starts watching on a subscription. * * Returns: %TRUE on success, %FALSE otherwise. **/ gboolean _kh_start_watching (kqueue_sub *sub) { g_assert (kqueue_socket_pair[0] != -1); g_assert (sub != NULL); g_assert (sub->filename != NULL); /* kqueue requires a file descriptor to monitor. Sad but true */ #if defined (O_EVTONLY) sub->fd = open (sub->filename, O_EVTONLY); #else sub->fd = open (sub->filename, O_RDONLY); #endif if (sub->fd == -1) { KH_W ("failed to open file %s (error %d)", sub->filename, errno); return FALSE; } _ku_file_information (sub->fd, &sub->is_dir, NULL); if (sub->is_dir) { /* I know, it is very bad to make such decisions in this way and here. * We already do have an user_data at the #kqueue_sub, and it may point to * GKqueueFileMonitor or GKqueueDirectoryMonitor. For a directory case, * we need to scan in contents for the further diffs. Ideally this process * should be delegated to the GKqueueDirectoryMonitor, but for now I will * do it in a dirty way right here. */ if (sub->deps) dl_free (sub->deps); sub->deps = dl_listing (sub->filename); } G_LOCK (hash_lock); g_hash_table_insert (subs_hash_table, GINT_TO_POINTER (sub->fd), sub); G_UNLOCK (hash_lock); _kqueue_thread_push_fd (sub->fd); /* Bump the kqueue thread. It will pick up a new sub entry to monitor */ if (!_ku_write (kqueue_socket_pair[0], "A", 1)) KH_W ("Failed to bump the kqueue thread (add fd, error %d)", errno); return TRUE; }