6a029ebed745994ce2e5f64182d8b5c8f10d53d6Timo Sirainen * BSD kqueue() based ioloop notify handler.
6a029ebed745994ce2e5f64182d8b5c8f10d53d6Timo Sirainen * Copyright (c) 2005 Vaclav Haisman <v.haisman@sh.cvut.cz>
f6c0407545ee77d4647c8cd912e3156b0a48e2f1Timo Sirainen/* kevent.udata's type just has to be different in NetBSD than in
f6c0407545ee77d4647c8cd912e3156b0a48e2f1Timo Sirainen FreeBSD and OpenBSD.. */
f6c0407545ee77d4647c8cd912e3156b0a48e2f1Timo Sirainen EV_SET(a, b, c, d, e, f, g)
fefe9afdb0fb4cfc70afe3006ec88ba09ab3762dTimo Sirainenio_loop_notify_free(struct ioloop_notify_handler_context *ctx,
2cfe9983ce7a6280636ee12beccc2e865111967bTimo Sirainenstatic void event_callback(struct ioloop_notify_handler_context *ctx)
fd1f0e9ef52b3e157cfd1a01c464c2ac7458ab17Timo Sirainen ret = kevent(ctx->kq, NULL, 0, events, N_ELEMENTS(events), &ts);
dcc76bb1e1bb287e3e71e6a39a7ca207fab0eaa8Timo Sirainen for (i = 0; i < ret; i++) {
dcc76bb1e1bb287e3e71e6a39a7ca207fab0eaa8Timo Sirainen for (i = 0; i < ret; i++) {
dcc76bb1e1bb287e3e71e6a39a7ca207fab0eaa8Timo Sirainen /* there can be multiple events for a single io.
dcc76bb1e1bb287e3e71e6a39a7ca207fab0eaa8Timo Sirainen call the callback only once if that happens. */
dcc76bb1e1bb287e3e71e6a39a7ca207fab0eaa8Timo Sirainen if (io->refcount == 2 && io->io.callback != NULL)
dcc76bb1e1bb287e3e71e6a39a7ca207fab0eaa8Timo Sirainenstatic struct ioloop_notify_handler_context *io_loop_notify_handler_init(void)
dcc76bb1e1bb287e3e71e6a39a7ca207fab0eaa8Timo Sirainen ctx = current_ioloop->notify_handler_context =
dcc76bb1e1bb287e3e71e6a39a7ca207fab0eaa8Timo Sirainen i_new(struct ioloop_notify_handler_context, 1);
6a029ebed745994ce2e5f64182d8b5c8f10d53d6Timo Sirainenvoid io_loop_notify_handler_deinit(struct ioloop *ioloop)
dfa23b2ddc43f323112225facf7cd7191e62e02cAki Tuomiio_add_notify(const char *path, const char *source_filename,
f6845101f2d6b8068e352a0b5a0d4bb04e20ad74Timo Sirainen io_callback_t *callback, void *context, struct io **io_r)
5c6410e8882d021ad9cff91d87b3ce68e309bd44Timo Sirainen /* ESTALE could happen with NFS. Don't bother giving an error
5c6410e8882d021ad9cff91d87b3ce68e309bd44Timo Sirainen message then. */
35565557e05721a761132cec2ba1d93acacb6c14Timo Sirainen i_error("open(%s) for kq notify failed: %m", path);
4dc5662260a63669054cd0dc1bac2ccab3fa2ae7Timo Sirainen /* EV_CLEAR flag is needed because the EVFILT_VNODE filter reports
4dc5662260a63669054cd0dc1bac2ccab3fa2ae7Timo Sirainen event state transitions and not the current state. With this flag,
4dc5662260a63669054cd0dc1bac2ccab3fa2ae7Timo Sirainen the same event is only returned once. */
f6c0407545ee77d4647c8cd912e3156b0a48e2f1Timo Sirainen MY_EV_SET(&ev, fd, EVFILT_VNODE, EV_ADD | EV_CLEAR,
f3739947c8a5f8584fe630ec138058c5bd53184fTimo Sirainen NOTE_DELETE | NOTE_RENAME | NOTE_WRITE | NOTE_EXTEND |
a40f21e8239a87a8fab2648955b0f568908ca8b5Timo Sirainen if (kevent(ctx->kq, &ev, 1, NULL, 0, NULL) < 0) {
a40f21e8239a87a8fab2648955b0f568908ca8b5Timo Sirainen i_error("kevent(%d, %s) for notify failed: %m", fd, path);
dcc76bb1e1bb287e3e71e6a39a7ca207fab0eaa8Timo Sirainen ctx->event_io = io_add(ctx->kq, IO_READ, event_callback,
dcc76bb1e1bb287e3e71e6a39a7ca207fab0eaa8Timo Sirainen struct io_notify *io = (struct io_notify *)_io;
f6c0407545ee77d4647c8cd912e3156b0a48e2f1Timo Sirainen MY_EV_SET(&ev, io->fd, EVFILT_VNODE, EV_DELETE, 0, 0, NULL);
a40f21e8239a87a8fab2648955b0f568908ca8b5Timo Sirainen i_error("kevent(%d) for notify remove failed: %m", io->fd);
35565557e05721a761132cec2ba1d93acacb6c14Timo Sirainen i_error("close(%d) for notify remove failed: %m", io->fd);
dad206f8341603837b7de4309a7c195da26cf9aaTimo Sirainenint io_loop_extract_notify_fd(struct ioloop *ioloop)
a350c75b6e22e6e8f246964924d9a4715d16af08Timo Sirainen for (io = ctx->notifies; io != NULL; io = io->next)