diff --git a/src/lib/ioloop-notify-inotify.c b/src/lib/ioloop-notify-inotify.c index a32cca0469..e5358709b6 100644 --- a/src/lib/ioloop-notify-inotify.c +++ b/src/lib/ioloop-notify-inotify.c @@ -86,7 +86,8 @@ static void inotify_input(struct ioloop *ioloop) #undef io_add_notify enum io_notify_result -io_add_notify(const char *path, unsigned int source_linenum, +io_add_notify(const char *path, const char *source_filename, + unsigned int source_linenum, io_callback_t *callback, void *context, struct io **io_r) { struct ioloop_notify_handler_context *ctx = @@ -126,6 +127,7 @@ io_add_notify(const char *path, unsigned int source_linenum, } *io_r = io_notify_fd_add(&ctx->fd_ctx, wd, callback, context); + (*io_r)->source_filename = source_filename; (*io_r)->source_linenum = source_linenum; return IO_NOTIFY_ADDED; } @@ -197,8 +199,9 @@ void io_loop_notify_handler_deinit(struct ioloop *ioloop) struct io_notify *io = ctx->fd_ctx.notifies; struct io *_io = &io->io; - i_warning("I/O notify leak: %p (line %u, fd %d)", + i_warning("I/O notify leak: %p (%s:%u, fd %d)", (void *)_io->callback, + _io->source_filename, _io->source_linenum, io->fd); io_remove(&_io); } diff --git a/src/lib/ioloop-notify-kqueue.c b/src/lib/ioloop-notify-kqueue.c index 5f40578d56..da5bd10c27 100644 --- a/src/lib/ioloop-notify-kqueue.c +++ b/src/lib/ioloop-notify-kqueue.c @@ -111,8 +111,9 @@ void io_loop_notify_handler_deinit(struct ioloop *ioloop) struct io_notify *io = ctx->notifies; struct io *_io = &io->io; - i_warning("I/O notify leak: %p (line %u, fd %d)", + i_warning("I/O notify leak: %p (%s:%u, fd %d)", (void *)_io->callback, + _io->source_filename, _io->source_linenum, io->fd); io_remove(&_io); } @@ -126,7 +127,8 @@ void io_loop_notify_handler_deinit(struct ioloop *ioloop) #undef io_add_notify enum io_notify_result -io_add_notify(const char *path, unsigned int source_linenum, +io_add_notify(const char *path, const char *source_filename, + unsigned int source_linenum, io_callback_t *callback, void *context, struct io **io_r) { struct ioloop_notify_handler_context *ctx = diff --git a/src/lib/ioloop-notify-none.c b/src/lib/ioloop-notify-none.c index f27c2bfcd7..831c088890 100644 --- a/src/lib/ioloop-notify-none.c +++ b/src/lib/ioloop-notify-none.c @@ -8,6 +8,7 @@ #undef io_add_notify enum io_notify_result io_add_notify(const char *path ATTR_UNUSED, + const char *source_filename ATTR_UNUSED, unsigned int source_linenum ATTR_UNUSED, io_callback_t *callback ATTR_UNUSED, void *context ATTR_UNUSED, struct io **io_r) diff --git a/src/lib/ioloop-private.h b/src/lib/ioloop-private.h index b50f86179e..3c3349c020 100644 --- a/src/lib/ioloop-private.h +++ b/src/lib/ioloop-private.h @@ -35,6 +35,7 @@ struct ioloop { struct io { enum io_condition condition; + const char *source_filename; unsigned int source_linenum; /* trigger I/O callback even if OS doesn't think there is input pending */ @@ -62,6 +63,7 @@ struct io_file { struct timeout { struct priorityq_item item; + const char *source_filename; unsigned int source_linenum; unsigned int msecs; diff --git a/src/lib/ioloop.c b/src/lib/ioloop.c index 96c3e7a654..3a948af4bb 100644 --- a/src/lib/ioloop.c +++ b/src/lib/ioloop.c @@ -31,6 +31,7 @@ static void io_loop_initialize_handler(struct ioloop *ioloop) static struct io_file * io_add_file(int fd, enum io_condition condition, + const char *source_filename, unsigned int source_linenum, io_callback_t *callback, void *context) { @@ -44,6 +45,7 @@ io_add_file(int fd, enum io_condition condition, io->io.callback = callback; io->io.context = context; io->io.ioloop = current_ioloop; + io->io.source_filename = source_filename; io->io.source_linenum = source_linenum; io->refcount = 1; io->fd = fd; @@ -72,24 +74,26 @@ io_add_file(int fd, enum io_condition condition, #undef io_add struct io *io_add(int fd, enum io_condition condition, + const char *source_filename, unsigned int source_linenum, io_callback_t *callback, void *context) { struct io_file *io; i_assert(fd >= 0); - io = io_add_file(fd, condition, source_linenum, callback, context); + io = io_add_file(fd, condition, source_filename, source_linenum, callback, context); return &io->io; } #undef io_add_istream -struct io *io_add_istream(struct istream *input, unsigned int source_linenum, +struct io *io_add_istream(struct istream *input, const char *source_filename, + unsigned int source_linenum, io_callback_t *callback, void *context) { struct io_file *io; - io = io_add_file(i_stream_get_fd(input), IO_READ, source_linenum, - callback, context); + io = io_add_file(i_stream_get_fd(input), IO_READ, source_filename, + source_linenum, callback, context); io->istream = input; i_stream_ref(io->istream); i_stream_set_io(io->istream, &io->io); @@ -203,13 +207,14 @@ static void timeout_update_next(struct timeout *timeout, struct timeval *tv_now) } static struct timeout * -timeout_add_common(unsigned int source_linenum, +timeout_add_common(const char *source_filename, unsigned int source_linenum, timeout_callback_t *callback, void *context) { struct timeout *timeout; timeout = i_new(struct timeout, 1); timeout->item.idx = UINT_MAX; + timeout->source_filename = source_filename; timeout->source_linenum = source_linenum; timeout->ioloop = current_ioloop; @@ -225,12 +230,13 @@ timeout_add_common(unsigned int source_linenum, } #undef timeout_add -struct timeout *timeout_add(unsigned int msecs, unsigned int source_linenum, +struct timeout *timeout_add(unsigned int msecs, const char *source_filename, + unsigned int source_linenum, timeout_callback_t *callback, void *context) { struct timeout *timeout; - timeout = timeout_add_common(source_linenum, callback, context); + timeout = timeout_add_common(source_filename, source_linenum, callback, context); timeout->msecs = msecs; if (msecs > 0) { @@ -247,21 +253,24 @@ struct timeout *timeout_add(unsigned int msecs, unsigned int source_linenum, #undef timeout_add_short struct timeout * -timeout_add_short(unsigned int msecs, unsigned int source_linenum, +timeout_add_short(unsigned int msecs, const char *source_filename, + unsigned int source_linenum, timeout_callback_t *callback, void *context) { - return timeout_add(msecs, source_linenum, callback, context); + return timeout_add(msecs, source_filename, source_linenum, callback, context); } #undef timeout_add_absolute struct timeout * timeout_add_absolute(const struct timeval *time, + const char *source_filename, unsigned int source_linenum, timeout_callback_t *callback, void *context) { struct timeout *timeout; - timeout = timeout_add_common(source_linenum, callback, context); + timeout = timeout_add_common(source_filename, source_linenum, + callback, context); timeout->one_shot = TRUE; timeout->next_run = *time; @@ -275,7 +284,8 @@ timeout_copy(const struct timeout *old_to) struct timeout *new_to; new_to = timeout_add_common - (old_to->source_linenum, old_to->callback, old_to->context); + (old_to->source_filename, old_to->source_linenum, + old_to->callback, old_to->context); new_to->one_shot = old_to->one_shot; new_to->msecs = old_to->msecs; new_to->next_run = old_to->next_run; @@ -691,8 +701,9 @@ void io_loop_destroy(struct ioloop **_ioloop) struct io_file *io = ioloop->io_files; struct io *_io = &io->io; - i_warning("I/O leak: %p (line %u, fd %d)", + i_warning("I/O leak: %p (%s:%u, fd %d)", (void *)io->io.callback, + io->io.source_filename, io->io.source_linenum, io->fd); io_remove(&_io); } @@ -701,7 +712,8 @@ void io_loop_destroy(struct ioloop **_ioloop) array_foreach(&ioloop->timeouts_new, to_idx) { struct timeout *to = *to_idx; - i_warning("Timeout leak: %p (line %u)", (void *)to->callback, + i_warning("Timeout leak: %p (%s:%u)", (void *)to->callback, + to->source_filename, to->source_linenum); timeout_free(to); } @@ -710,7 +722,8 @@ void io_loop_destroy(struct ioloop **_ioloop) while ((item = priorityq_pop(ioloop->timeouts)) != NULL) { struct timeout *to = (struct timeout *)item; - i_warning("Timeout leak: %p (line %u)", (void *)to->callback, + i_warning("Timeout leak: %p (%s:%u)", (void *)to->callback, + to->source_filename, to->source_linenum); timeout_free(to); } @@ -918,6 +931,7 @@ struct io *io_loop_move_io(struct io **_io) old_io_file = (struct io_file *)old_io; new_io_file = io_add_file(old_io_file->fd, old_io->condition, + old_io->source_filename, old_io->source_linenum, old_io->callback, old_io->context); if (old_io_file->istream != NULL) { diff --git a/src/lib/ioloop.h b/src/lib/ioloop.h index 229f73dc17..4db2903482 100644 --- a/src/lib/ioloop.h +++ b/src/lib/ioloop.h @@ -48,24 +48,27 @@ extern struct ioloop *current_ioloop; Don't try to add multiple handlers for the same type. It's not checked and the behavior will be undefined. */ struct io *io_add(int fd, enum io_condition condition, + const char *source_filename, unsigned int source_linenum, io_callback_t *callback, void *context) ATTR_NULL(5); #define io_add(fd, condition, callback, context) \ - io_add(fd, condition, __LINE__ + \ + io_add(fd, condition, __FILE__, __LINE__ + \ CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \ (io_callback_t *)callback, context) enum io_notify_result -io_add_notify(const char *path, unsigned int source_linenum, +io_add_notify(const char *path, const char *source_filename, + unsigned int source_linenum, io_callback_t *callback, void *context, struct io **io_r) ATTR_NULL(3); #define io_add_notify(path, callback, context, io_r) \ - io_add_notify(path, __LINE__ + \ + io_add_notify(path, __FILE__, __LINE__ + \ CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \ (io_callback_t *)callback, context, io_r) -struct io *io_add_istream(struct istream *input, unsigned int source_linenum, +struct io *io_add_istream(struct istream *input, const char *source_filename, + unsigned int source_linenum, io_callback_t *callback, void *context) ATTR_NULL(3); #define io_add_istream(input, callback, context) \ - io_add_istream(input, __LINE__ + \ + io_add_istream(input, __FILE__, __LINE__ + \ CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \ (io_callback_t *)callback, context) @@ -83,26 +86,29 @@ void io_set_pending(struct io *io); /* Timeout handlers */ struct timeout * -timeout_add(unsigned int msecs, unsigned int source_linenum, +timeout_add(unsigned int msecs, const char *source_filename, + unsigned int source_linenum, timeout_callback_t *callback, void *context) ATTR_NULL(4); #define timeout_add(msecs, callback, context) \ - timeout_add(msecs, __LINE__ + \ + timeout_add(msecs, __FILE__, __LINE__ + \ CALLBACK_TYPECHECK(callback, void (*)(typeof(context))) + \ COMPILE_ERROR_IF_TRUE(__builtin_constant_p(msecs) && \ (msecs > 0 && msecs < 1000)), \ (io_callback_t *)callback, context) struct timeout * -timeout_add_short(unsigned int msecs, unsigned int source_linenum, +timeout_add_short(unsigned int msecs, const char *source_filename, + unsigned int source_linenum, timeout_callback_t *callback, void *context) ATTR_NULL(4); #define timeout_add_short(msecs, callback, context) \ - timeout_add_short(msecs, __LINE__ + \ + timeout_add_short(msecs, __FILE__, __LINE__ + \ CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \ (io_callback_t *)callback, context) struct timeout *timeout_add_absolute(const struct timeval *time, + const char *source_filename, unsigned int source_linenum, timeout_callback_t *callback, void *context) ATTR_NULL(4); #define timeout_add_absolute(time, callback, context) \ - timeout_add_absolute(time, __LINE__ + \ + timeout_add_absolute(time, __FILE__, __LINE__ + \ CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \ (io_callback_t *)callback, context) /* Remove timeout handler, and set timeout pointer to NULL. */