diff options
Diffstat (limited to '')
-rw-r--r-- | src/InotifySource.cxx | 100 | ||||
-rw-r--r-- | src/InotifySource.hxx | 76 | ||||
-rw-r--r-- | src/InotifyUpdate.cxx | 18 |
3 files changed, 96 insertions, 98 deletions
diff --git a/src/InotifySource.cxx b/src/InotifySource.cxx index 16fd62511..f795733d8 100644 --- a/src/InotifySource.cxx +++ b/src/InotifySource.cxx @@ -36,22 +36,6 @@ extern "C" { #undef G_LOG_DOMAIN #define G_LOG_DOMAIN "inotify" -struct mpd_inotify_source { - int fd; - - GIOChannel *channel; - - /** - * The channel's source id in the GLib main loop. - */ - guint id; - - struct fifo_buffer *buffer; - - mpd_inotify_callback_t callback; - void *callback_ctx; -}; - /** * A GQuark for GError instances. */ @@ -61,35 +45,32 @@ mpd_inotify_quark(void) return g_quark_from_static_string("inotify"); } -static gboolean -mpd_inotify_in_event(G_GNUC_UNUSED GIOChannel *_source, - G_GNUC_UNUSED GIOCondition condition, - gpointer data) +inline void +InotifySource::InEvent() { - struct mpd_inotify_source *source = (struct mpd_inotify_source *)data; void *dest; size_t length; ssize_t nbytes; - dest = fifo_buffer_write(source->buffer, &length); + dest = fifo_buffer_write(buffer, &length); if (dest == NULL) MPD_ERROR("buffer full"); - nbytes = read(source->fd, dest, length); + nbytes = read(fd, dest, length); if (nbytes < 0) MPD_ERROR("failed to read from inotify: %s", g_strerror(errno)); if (nbytes == 0) MPD_ERROR("end of file from inotify"); - fifo_buffer_append(source->buffer, nbytes); + fifo_buffer_append(buffer, nbytes); while (true) { const char *name; const struct inotify_event *event = (const struct inotify_event *) - fifo_buffer_read(source->buffer, &length); + fifo_buffer_read(buffer, &length); if (event == NULL || length < sizeof(*event) || length < sizeof(*event) + event->len) break; @@ -99,59 +80,58 @@ mpd_inotify_in_event(G_GNUC_UNUSED GIOChannel *_source, else name = NULL; - source->callback(event->wd, event->mask, name, - source->callback_ctx); - fifo_buffer_consume(source->buffer, - sizeof(*event) + event->len); + callback(event->wd, event->mask, name, callback_ctx); + fifo_buffer_consume(buffer, sizeof(*event) + event->len); } +} +gboolean +InotifySource::InEvent(G_GNUC_UNUSED GIOChannel *_source, + G_GNUC_UNUSED GIOCondition condition, + gpointer data) +{ + InotifySource &source = *(InotifySource *)data; + source.InEvent(); return true; } -struct mpd_inotify_source * -mpd_inotify_source_new(mpd_inotify_callback_t callback, void *callback_ctx, - GError **error_r) +inline +InotifySource::InotifySource(mpd_inotify_callback_t _callback, void *_ctx, + int _fd) + :callback(_callback), callback_ctx(_ctx), fd(_fd), + channel(g_io_channel_unix_new(fd)), + id(g_io_add_watch(channel, G_IO_IN, InEvent, this)), + buffer(fifo_buffer_new(4096)) { - struct mpd_inotify_source *source = - g_new(struct mpd_inotify_source, 1); +} - source->fd = inotify_init_cloexec(); - if (source->fd < 0) { +InotifySource * +InotifySource::Create(mpd_inotify_callback_t callback, void *callback_ctx, + GError **error_r) +{ + int fd = inotify_init_cloexec(); + if (fd < 0) { g_set_error(error_r, mpd_inotify_quark(), errno, "inotify_init() has failed: %s", g_strerror(errno)); - g_free(source); return NULL; } - source->buffer = fifo_buffer_new(4096); - - source->channel = g_io_channel_unix_new(source->fd); - source->id = g_io_add_watch(source->channel, G_IO_IN, - mpd_inotify_in_event, source); - - source->callback = callback; - source->callback_ctx = callback_ctx; - - return source; + return new InotifySource(callback, callback_ctx, fd); } -void -mpd_inotify_source_free(struct mpd_inotify_source *source) +InotifySource::~InotifySource() { - g_source_remove(source->id); - g_io_channel_unref(source->channel); - fifo_buffer_free(source->buffer); - close(source->fd); - g_free(source); + g_source_remove(id); + g_io_channel_unref(channel); + fifo_buffer_free(buffer); + close(fd); } int -mpd_inotify_source_add(struct mpd_inotify_source *source, - const char *path_fs, unsigned mask, - GError **error_r) +InotifySource::Add(const char *path_fs, unsigned mask, GError **error_r) { - int wd = inotify_add_watch(source->fd, path_fs, mask); + int wd = inotify_add_watch(fd, path_fs, mask); if (wd < 0) g_set_error(error_r, mpd_inotify_quark(), errno, "inotify_add_watch() has failed: %s", @@ -161,9 +141,9 @@ mpd_inotify_source_add(struct mpd_inotify_source *source, } void -mpd_inotify_source_rm(struct mpd_inotify_source *source, unsigned wd) +InotifySource::Remove(unsigned wd) { - int ret = inotify_rm_watch(source->fd, wd); + int ret = inotify_rm_watch(fd, wd); if (ret < 0 && errno != EINVAL) g_warning("inotify_rm_watch() has failed: %s", g_strerror(errno)); diff --git a/src/InotifySource.hxx b/src/InotifySource.hxx index cde2bc269..6299d1e20 100644 --- a/src/InotifySource.hxx +++ b/src/InotifySource.hxx @@ -22,40 +22,60 @@ #include "gerror.h" +#include <glib.h> + typedef void (*mpd_inotify_callback_t)(int wd, unsigned mask, const char *name, void *ctx); -struct mpd_inotify_source; +class InotifySource { + mpd_inotify_callback_t callback; + void *callback_ctx; -/** - * Creates a new inotify source and registers it in the GLib main - * loop. - * - * @param a callback invoked for events received from the kernel - */ -struct mpd_inotify_source * -mpd_inotify_source_new(mpd_inotify_callback_t callback, void *callback_ctx, - GError **error_r); + int fd; -void -mpd_inotify_source_free(struct mpd_inotify_source *source); + GIOChannel *channel; -/** - * Adds a path to the notify list. - * - * @return a watch descriptor or -1 on error - */ -int -mpd_inotify_source_add(struct mpd_inotify_source *source, - const char *path_fs, unsigned mask, - GError **error_r); + /** + * The channel's source id in the GLib main loop. + */ + guint id; -/** - * Removes a path from the notify list. - * - * @param wd the watch descriptor returned by mpd_inotify_source_add() - */ -void -mpd_inotify_source_rm(struct mpd_inotify_source *source, unsigned wd); + struct fifo_buffer *buffer; + + InotifySource(mpd_inotify_callback_t callback, void *ctx, int fd); + +public: + /** + * Creates a new inotify source and registers it in the GLib main + * loop. + * + * @param a callback invoked for events received from the kernel + */ + static InotifySource *Create(mpd_inotify_callback_t callback, + void *ctx, + GError **error_r); + + ~InotifySource(); + + + /** + * Adds a path to the notify list. + * + * @return a watch descriptor or -1 on error + */ + int Add(const char *path_fs, unsigned mask, GError **error_r); + + /** + * Removes a path from the notify list. + * + * @param wd the watch descriptor returned by mpd_inotify_source_add() + */ + void Remove(unsigned wd); + +private: + void InEvent(); + static gboolean InEvent(GIOChannel *source, GIOCondition condition, + gpointer data); +}; #endif diff --git a/src/InotifyUpdate.cxx b/src/InotifyUpdate.cxx index b7bb3af2b..41b93a299 100644 --- a/src/InotifyUpdate.cxx +++ b/src/InotifyUpdate.cxx @@ -56,7 +56,7 @@ struct watch_directory { GList *children; }; -static struct mpd_inotify_source *inotify_source; +static InotifySource *inotify_source; static unsigned inotify_max_depth; static struct watch_directory inotify_root; @@ -117,7 +117,7 @@ remove_watch_directory(struct watch_directory *directory) directory->parent->children = g_list_remove(directory->parent->children, directory); - mpd_inotify_source_rm(inotify_source, directory->descriptor); + inotify_source->Remove(directory->descriptor); g_free(directory->name); g_slice_free(struct watch_directory, directory); } @@ -195,8 +195,7 @@ recursive_watch_subdirectories(struct watch_directory *directory, continue; } - ret = mpd_inotify_source_add(inotify_source, child_path_fs, - IN_MASK, &error); + ret = inotify_source->Add(child_path_fs, IN_MASK, &error); if (ret < 0) { g_warning("Failed to register %s: %s", child_path_fs, error->message); @@ -317,8 +316,8 @@ mpd_inotify_init(unsigned max_depth) return; } - inotify_source = mpd_inotify_source_new(mpd_inotify_callback, NULL, - &error); + inotify_source = InotifySource::Create(mpd_inotify_callback, nullptr, + &error); if (inotify_source == NULL) { g_warning("%s", error->message); g_error_free(error); @@ -328,12 +327,11 @@ mpd_inotify_init(unsigned max_depth) inotify_max_depth = max_depth; inotify_root.name = g_strdup(path); - inotify_root.descriptor = mpd_inotify_source_add(inotify_source, path, - IN_MASK, &error); + inotify_root.descriptor = inotify_source->Add(path, IN_MASK, &error); if (inotify_root.descriptor < 0) { g_warning("%s", error->message); g_error_free(error); - mpd_inotify_source_free(inotify_source); + delete inotify_source; inotify_source = NULL; return; } @@ -370,7 +368,7 @@ mpd_inotify_finish(void) return; mpd_inotify_queue_finish(); - mpd_inotify_source_free(inotify_source); + delete inotify_source; g_tree_foreach(inotify_directories, free_watch_directory, NULL); g_tree_destroy(inotify_directories); |