dovecot-1.2: Added io_remove_closed().
dovecot at dovecot.org
dovecot at dovecot.org
Thu Aug 21 07:36:50 EEST 2008
details: http://hg.dovecot.org/dovecot-1.2/rev/83aef3a6c0a3
changeset: 8100:83aef3a6c0a3
user: Timo Sirainen <tss at iki.fi>
date: Thu Aug 21 07:35:59 2008 +0300
description:
Added io_remove_closed().
diffstat:
7 files changed, 54 insertions(+), 30 deletions(-)
src/lib/ioloop-epoll.c | 26 ++++++++++++++------------
src/lib/ioloop-internal.h | 3 ++-
src/lib/ioloop-kqueue.c | 7 ++++---
src/lib/ioloop-poll.c | 24 ++++++++++++++----------
src/lib/ioloop-select.c | 3 ++-
src/lib/ioloop.c | 18 +++++++++++++++---
src/lib/ioloop.h | 3 +++
diffs (183 lines):
diff -r 060165bdb0b0 -r 83aef3a6c0a3 src/lib/ioloop-epoll.c
--- a/src/lib/ioloop-epoll.c Thu Aug 21 07:14:50 2008 +0300
+++ b/src/lib/ioloop-epoll.c Thu Aug 21 07:35:59 2008 +0300
@@ -118,7 +118,8 @@ void io_loop_handle_add(struct ioloop *i
}
}
-void io_loop_handle_remove(struct ioloop *ioloop, struct io_file *io)
+void io_loop_handle_remove(struct ioloop *ioloop, struct io_file *io,
+ bool closed)
{
struct ioloop_handler_context *ctx = ioloop->handler_context;
struct io_list **list;
@@ -129,17 +130,18 @@ void io_loop_handle_remove(struct ioloop
list = array_idx_modifiable(&ctx->fd_index, io->fd);
last = ioloop_iolist_del(*list, io);
- memset(&event, 0, sizeof(event));
- event.data.ptr = *list;
- event.events = epoll_event_mask(*list);
-
- op = last ? EPOLL_CTL_DEL : EPOLL_CTL_MOD;
-
- if (epoll_ctl(ctx->epfd, op, io->fd, &event) < 0) {
- i_error("io_loop_handle_remove: epoll_ctl(%d, %d): %m",
- op, io->fd);
- }
-
+ if (!closed) {
+ memset(&event, 0, sizeof(event));
+ event.data.ptr = *list;
+ event.events = epoll_event_mask(*list);
+
+ op = last ? EPOLL_CTL_DEL : EPOLL_CTL_MOD;
+
+ if (epoll_ctl(ctx->epfd, op, io->fd, &event) < 0) {
+ i_error("io_loop_handle_remove: epoll_ctl(%d, %d): %m",
+ op, io->fd);
+ }
+ }
if (last) {
/* since we're not freeing memory in any case, just increase
deleted counter so next handle_add() can just decrease it
diff -r 060165bdb0b0 -r 83aef3a6c0a3 src/lib/ioloop-internal.h
--- a/src/lib/ioloop-internal.h Thu Aug 21 07:14:50 2008 +0300
+++ b/src/lib/ioloop-internal.h Thu Aug 21 07:35:59 2008 +0300
@@ -54,7 +54,8 @@ void io_loop_handle_timeouts(struct iolo
/* I/O handler calls */
void io_loop_handle_add(struct ioloop *ioloop, struct io_file *io);
-void io_loop_handle_remove(struct ioloop *ioloop, struct io_file *io);
+void io_loop_handle_remove(struct ioloop *ioloop, struct io_file *io,
+ bool closed);
void io_loop_handler_init(struct ioloop *ioloop);
void io_loop_handler_deinit(struct ioloop *ioloop);
diff -r 060165bdb0b0 -r 83aef3a6c0a3 src/lib/ioloop-kqueue.c
--- a/src/lib/ioloop-kqueue.c Thu Aug 21 07:14:50 2008 +0300
+++ b/src/lib/ioloop-kqueue.c Thu Aug 21 07:35:59 2008 +0300
@@ -80,17 +80,18 @@ void io_loop_handle_add(struct ioloop *i
(void)array_append_space(&ctx->events);
}
-void io_loop_handle_remove(struct ioloop *ioloop, struct io_file *io)
+void io_loop_handle_remove(struct ioloop *ioloop, struct io_file *io,
+ bool closed)
{
struct ioloop_handler_context *ctx = ioloop->handler_context;
struct kevent ev;
- if ((io->io.condition & (IO_READ | IO_ERROR)) != 0) {
+ if ((io->io.condition & (IO_READ | IO_ERROR)) != 0 && !closed) {
MY_EV_SET(&ev, io->fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
if (kevent(ctx->kq, &ev, 1, NULL, 0, NULL) < 0)
i_error("kevent(EV_DELETE, %d) failed: %m", io->fd);
}
- if ((io->io.condition & IO_WRITE) != 0) {
+ if ((io->io.condition & IO_WRITE) != 0 && !closed) {
MY_EV_SET(&ev, io->fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
if (kevent(ctx->kq, &ev, 1, NULL, 0, NULL) < 0)
i_error("kevent(EV_DELETE, %d) failed: %m", io->fd);
diff -r 060165bdb0b0 -r 83aef3a6c0a3 src/lib/ioloop-poll.c
--- a/src/lib/ioloop-poll.c Thu Aug 21 07:14:50 2008 +0300
+++ b/src/lib/ioloop-poll.c Thu Aug 21 07:35:59 2008 +0300
@@ -94,7 +94,8 @@ void io_loop_handle_add(struct ioloop *i
ctx->fds[index].events |= IO_POLL_ERROR;
}
-void io_loop_handle_remove(struct ioloop *ioloop, struct io_file *io)
+void io_loop_handle_remove(struct ioloop *ioloop, struct io_file *io,
+ bool closed ATTR_UNUSED)
{
struct ioloop_handler_context *ctx = ioloop->handler_context;
enum io_condition condition = io->io.condition;
@@ -104,15 +105,18 @@ void io_loop_handle_remove(struct ioloop
i_assert(index >= 0 && (unsigned int) index < ctx->fds_count);
#ifdef DEBUG
- /* io_remove() is required to be called before fd is closed.
- This is required by kqueue, but since poll is more commonly used
- while developing, this check here should catch the error early
- enough not to cause problems for kqueue users. */
- if (fcntl(io->fd, F_GETFD, 0) < 0) {
- if (errno == EBADF)
- i_panic("io_remove(%d) called too late", io->fd);
- else
- i_error("fcntl(%d, F_GETFD) failed: %m", io->fd);
+ if (!closed) {
+ /* io_remove() is required to be called before fd is closed.
+ This is required by epoll/kqueue, but since poll is more
+ commonly used while developing, this check here should catch
+ the error early enough not to cause problems for kqueue
+ users. */
+ if (fcntl(io->fd, F_GETFD, 0) < 0) {
+ if (errno == EBADF)
+ i_panic("io_remove(%d) called too late", io->fd);
+ else
+ i_error("fcntl(%d, F_GETFD) failed: %m", io->fd);
+ }
}
#endif
i_free(io);
diff -r 060165bdb0b0 -r 83aef3a6c0a3 src/lib/ioloop-select.c
--- a/src/lib/ioloop-select.c Thu Aug 21 07:14:50 2008 +0300
+++ b/src/lib/ioloop-select.c Thu Aug 21 07:35:59 2008 +0300
@@ -74,7 +74,8 @@ void io_loop_handle_add(struct ioloop *i
ctx->highest_fd = io->fd;
}
-void io_loop_handle_remove(struct ioloop *ioloop, struct io_file *io)
+void io_loop_handle_remove(struct ioloop *ioloop, struct io_file *io,
+ bool closed ATTR_UNUSED)
{
struct ioloop_handler_context *ctx = ioloop->handler_context;
enum io_condition condition = io->io.condition;
diff -r 060165bdb0b0 -r 83aef3a6c0a3 src/lib/ioloop.c
--- a/src/lib/ioloop.c Thu Aug 21 07:14:50 2008 +0300
+++ b/src/lib/ioloop.c Thu Aug 21 07:35:59 2008 +0300
@@ -64,7 +64,7 @@ static void io_file_unlink(struct io_fil
current_ioloop->next_io_file = io->next;
}
-void io_remove(struct io **_io)
+static void io_remove_full(struct io **_io, bool closed)
{
struct io *io = *_io;
@@ -82,8 +82,20 @@ void io_remove(struct io **_io)
struct io_file *io_file = (struct io_file *)io;
io_file_unlink(io_file);
- io_loop_handle_remove(current_ioloop, io_file);
- }
+ io_loop_handle_remove(current_ioloop, io_file, closed);
+ }
+}
+
+void io_remove(struct io **io)
+{
+ io_remove_full(io, FALSE);
+}
+
+void io_remove_closed(struct io **io)
+{
+ i_assert(((*io)->condition & IO_NOTIFY) == 0);
+
+ io_remove_full(io, TRUE);
}
static void timeout_update_next(struct timeout *timeout, struct timeval *tv_now)
diff -r 060165bdb0b0 -r 83aef3a6c0a3 src/lib/ioloop.h
--- a/src/lib/ioloop.h Thu Aug 21 07:14:50 2008 +0300
+++ b/src/lib/ioloop.h Thu Aug 21 07:35:59 2008 +0300
@@ -63,6 +63,9 @@ enum io_notify_result io_add_notify(cons
/* Remove I/O handler, and set io pointer to NULL. */
void io_remove(struct io **io);
+/* Like io_remove(), but assume that the file descriptor is already closed.
+ With some backends this simply frees the memory. */
+void io_remove_closed(struct io **io);
/* Timeout handlers */
struct timeout *timeout_add(unsigned int msecs, timeout_callback_t *callback,
More information about the dovecot-cvs
mailing list