Commit 70711267 authored by Max Kellermann's avatar Max Kellermann

InotifySource: use the SocketMonitor class

parent 2101daef
...@@ -1335,6 +1335,7 @@ test_run_inotify_SOURCES = test/run_inotify.cxx \ ...@@ -1335,6 +1335,7 @@ test_run_inotify_SOURCES = test/run_inotify.cxx \
src/fd_util.c \ src/fd_util.c \
src/InotifySource.cxx src/InotifySource.cxx
test_run_inotify_LDADD = \ test_run_inotify_LDADD = \
libevent.a \
libutil.a \ libutil.a \
$(GLIB_LIBS) $(GLIB_LIBS)
endif endif
......
...@@ -41,8 +41,8 @@ mpd_inotify_quark(void) ...@@ -41,8 +41,8 @@ mpd_inotify_quark(void)
return g_quark_from_static_string("inotify"); return g_quark_from_static_string("inotify");
} }
inline void void
InotifySource::InEvent() InotifySource::OnSocketReady(gcc_unused unsigned flags)
{ {
void *dest; void *dest;
size_t length; size_t length;
...@@ -52,7 +52,7 @@ InotifySource::InEvent() ...@@ -52,7 +52,7 @@ InotifySource::InEvent()
if (dest == NULL) if (dest == NULL)
MPD_ERROR("buffer full"); MPD_ERROR("buffer full");
nbytes = read(fd, dest, length); nbytes = read(Get(), dest, length);
if (nbytes < 0) if (nbytes < 0)
MPD_ERROR("failed to read from inotify: %s", MPD_ERROR("failed to read from inotify: %s",
g_strerror(errno)); g_strerror(errno));
...@@ -81,28 +81,21 @@ InotifySource::InEvent() ...@@ -81,28 +81,21 @@ InotifySource::InEvent()
} }
} }
gboolean
InotifySource::InEvent(G_GNUC_UNUSED GIOChannel *_source,
G_GNUC_UNUSED GIOCondition condition,
gpointer data)
{
InotifySource &source = *(InotifySource *)data;
source.InEvent();
return true;
}
inline inline
InotifySource::InotifySource(mpd_inotify_callback_t _callback, void *_ctx, InotifySource::InotifySource(EventLoop &_loop,
mpd_inotify_callback_t _callback, void *_ctx,
int _fd) int _fd)
:callback(_callback), callback_ctx(_ctx), fd(_fd), :SocketMonitor(_fd, _loop),
channel(g_io_channel_unix_new(fd)), callback(_callback), callback_ctx(_ctx),
id(g_io_add_watch(channel, G_IO_IN, InEvent, this)),
buffer(fifo_buffer_new(4096)) buffer(fifo_buffer_new(4096))
{ {
ScheduleRead();
} }
InotifySource * InotifySource *
InotifySource::Create(mpd_inotify_callback_t callback, void *callback_ctx, InotifySource::Create(EventLoop &loop,
mpd_inotify_callback_t callback, void *callback_ctx,
GError **error_r) GError **error_r)
{ {
int fd = inotify_init_cloexec(); int fd = inotify_init_cloexec();
...@@ -113,21 +106,18 @@ InotifySource::Create(mpd_inotify_callback_t callback, void *callback_ctx, ...@@ -113,21 +106,18 @@ InotifySource::Create(mpd_inotify_callback_t callback, void *callback_ctx,
return NULL; return NULL;
} }
return new InotifySource(callback, callback_ctx, fd); return new InotifySource(loop, callback, callback_ctx, fd);
} }
InotifySource::~InotifySource() InotifySource::~InotifySource()
{ {
g_source_remove(id);
g_io_channel_unref(channel);
fifo_buffer_free(buffer); fifo_buffer_free(buffer);
close(fd);
} }
int int
InotifySource::Add(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(fd, path_fs, mask); int wd = inotify_add_watch(Get(), path_fs, mask);
if (wd < 0) if (wd < 0)
g_set_error(error_r, mpd_inotify_quark(), errno, g_set_error(error_r, mpd_inotify_quark(), errno,
"inotify_add_watch() has failed: %s", "inotify_add_watch() has failed: %s",
...@@ -139,7 +129,7 @@ InotifySource::Add(const char *path_fs, unsigned mask, GError **error_r) ...@@ -139,7 +129,7 @@ InotifySource::Add(const char *path_fs, unsigned mask, GError **error_r)
void void
InotifySource::Remove(unsigned wd) InotifySource::Remove(unsigned wd)
{ {
int ret = inotify_rm_watch(fd, wd); int ret = inotify_rm_watch(Get(), wd);
if (ret < 0 && errno != EINVAL) if (ret < 0 && errno != EINVAL)
g_warning("inotify_rm_watch() has failed: %s", g_warning("inotify_rm_watch() has failed: %s",
g_strerror(errno)); g_strerror(errno));
......
...@@ -20,29 +20,23 @@ ...@@ -20,29 +20,23 @@
#ifndef MPD_INOTIFY_SOURCE_HXX #ifndef MPD_INOTIFY_SOURCE_HXX
#define MPD_INOTIFY_SOURCE_HXX #define MPD_INOTIFY_SOURCE_HXX
#include "event/SocketMonitor.hxx"
#include "gerror.h" #include "gerror.h"
#include "gcc.h"
#include <glib.h> #include <glib.h>
typedef void (*mpd_inotify_callback_t)(int wd, unsigned mask, typedef void (*mpd_inotify_callback_t)(int wd, unsigned mask,
const char *name, void *ctx); const char *name, void *ctx);
class InotifySource { class InotifySource final : private SocketMonitor {
mpd_inotify_callback_t callback; mpd_inotify_callback_t callback;
void *callback_ctx; void *callback_ctx;
int fd;
GIOChannel *channel;
/**
* The channel's source id in the GLib main loop.
*/
guint id;
struct fifo_buffer *buffer; struct fifo_buffer *buffer;
InotifySource(mpd_inotify_callback_t callback, void *ctx, int fd); InotifySource(EventLoop &_loop,
mpd_inotify_callback_t callback, void *ctx, int fd);
public: public:
/** /**
...@@ -51,7 +45,8 @@ public: ...@@ -51,7 +45,8 @@ public:
* *
* @param a callback invoked for events received from the kernel * @param a callback invoked for events received from the kernel
*/ */
static InotifySource *Create(mpd_inotify_callback_t callback, static InotifySource *Create(EventLoop &_loop,
mpd_inotify_callback_t callback,
void *ctx, void *ctx,
GError **error_r); GError **error_r);
...@@ -73,9 +68,7 @@ public: ...@@ -73,9 +68,7 @@ public:
void Remove(unsigned wd); void Remove(unsigned wd);
private: private:
void InEvent(); virtual void OnSocketReady(unsigned flags) override;
static gboolean InEvent(GIOChannel *source, GIOCondition condition,
gpointer data);
}; };
#endif #endif
...@@ -318,7 +318,8 @@ mpd_inotify_init(unsigned max_depth) ...@@ -318,7 +318,8 @@ mpd_inotify_init(unsigned max_depth)
return; return;
} }
inotify_source = InotifySource::Create(mpd_inotify_callback, nullptr, inotify_source = InotifySource::Create(*main_loop,
mpd_inotify_callback, nullptr,
&error); &error);
if (inotify_source == NULL) { if (inotify_source == NULL) {
g_warning("%s", error->message); g_warning("%s", error->message);
......
...@@ -61,7 +61,10 @@ int main(int argc, char **argv) ...@@ -61,7 +61,10 @@ int main(int argc, char **argv)
path = argv[1]; path = argv[1];
InotifySource *source = InotifySource::Create(my_inotify_callback, event_loop = new EventLoop(EventLoop::Default());
InotifySource *source = InotifySource::Create(*event_loop,
my_inotify_callback,
nullptr, &error); nullptr, &error);
if (source == NULL) { if (source == NULL) {
g_warning("%s", error->message); g_warning("%s", error->message);
...@@ -77,8 +80,6 @@ int main(int argc, char **argv) ...@@ -77,8 +80,6 @@ int main(int argc, char **argv)
return 2; return 2;
} }
event_loop = new EventLoop(EventLoop::Default());
struct sigaction sa; struct sigaction sa;
sa.sa_flags = 0; sa.sa_flags = 0;
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment