struct ioloop_notify_handler_context *ctx =
ioloop->notify_handler_context;
+ while (ctx->fd_ctx.notifies != NULL) {
+ struct io_notify *io = ctx->fd_ctx.notifies;
+ struct io *_io = &io->io;
+
+ i_warning("I/O notify leak: %p (line %u, fd %d)",
+ (void *)_io->callback,
+ _io->source_linenum, io->fd);
+ io_remove(&_io);
+ }
+
if (ctx->inotify_fd != -1) {
if (close(ctx->inotify_fd) < 0)
i_error("close(inotify) failed: %m");
#ifdef IOLOOP_NOTIFY_KQUEUE
#include "ioloop-private.h"
+#include "llist.h"
#include "fd-close-on-exec.h"
#include <unistd.h>
#include <fcntl.h>
struct io io;
int refcount;
int fd;
+ struct io_notify *prev, *next;
};
struct ioloop_notify_handler_context {
int kq;
struct io *event_io;
+ struct io_notify *notifies;
};
+static void
+io_loop_notify_free(struct ioloop_notify_handler_context *ctx,
+ struct io_notify *io)
+{
+ DLLIST_REMOVE(&ctx->notifies, io);
+ i_free(io);
+}
+
static void event_callback(struct ioloop_notify_handler_context *ctx)
{
struct io_notify *io;
io_loop_call_io(&io->io);
if (--io->refcount == 0)
- i_free(io);
+ io_loop_notify_free(ctx, io);
}
}
struct ioloop_notify_handler_context *ctx =
ioloop->notify_handler_context;
+ while (ctx->notifies != NULL) {
+ struct io_notify *io = ctx->notifies;
+ struct io *_io = &io->io;
+
+ i_warning("I/O notify leak: %p (line %u, fd %d)",
+ (void *)_io->callback,
+ _io->source_linenum, io->fd);
+ io_remove(&_io);
+ }
+
if (ctx->event_io)
io_remove(&ctx->event_io);
if (close(ctx->kq) < 0)
ctx->event_io = io_add(ctx->kq, IO_READ, event_callback,
io->io.ioloop->notify_handler_context);
}
+ DLLIST_PREPEND(&ctx->notifies, io);
*io_r = &io->io;
return IO_NOTIFY_ADDED;
}
io->fd = -1;
if (--io->refcount == 0)
- i_free(io);
+ io_loop_notify_free(ctx, io);
}
#endif