changeset 4576:6dd7388db4a8 HEAD

Fixes
author Timo Sirainen <tss@iki.fi>
date Thu, 17 Aug 2006 00:33:40 +0300
parents ba4f580c5ec7
children afbe8e85e5d6
files src/lib/ioloop-epoll.c src/lib/ioloop-kqueue.c
diffstat 2 files changed, 26 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/ioloop-epoll.c	Wed Aug 16 23:48:35 2006 +0300
+++ b/src/lib/ioloop-epoll.c	Thu Aug 17 00:33:40 2006 +0300
@@ -21,8 +21,8 @@
 	int epfd;
 
 	unsigned int deleted_count;
-	array_t ARRAY_DEFINE(fd_index, struct io_list *);
-	array_t ARRAY_DEFINE(events, struct epoll_event);
+	ARRAY_DEFINE(fd_index, struct io_list *);
+	ARRAY_DEFINE(events, struct epoll_event);
 };
 
 void io_loop_handler_init(struct ioloop *ioloop)
@@ -146,35 +146,37 @@
 void io_loop_handler_run(struct ioloop *ioloop)
 {
 	struct ioloop_handler_context *ctx = ioloop->handler_context;
-	struct epoll_event *event;
+	struct epoll_event *events;
+	const struct epoll_event *event;
 	struct io_list *list;
 	struct io *io;
 	struct timeval tv;
 	unsigned int events_count, t_id;
-	int msecs, ret, i;
+	int msecs, ret, i, j;
 	bool call;
 
         /* get the time left for next timeout task */
 	msecs = io_loop_get_wait_time(ioloop->timeouts, &tv, NULL);
 
-	event = array_get_modifiable(&ctx->events, &events_count);
-	ret = epoll_wait(ctx->epfd, event, events_count, msecs);
+	events = array_get_modifiable(&ctx->events, &events_count);
+	ret = epoll_wait(ctx->epfd, events, events_count, msecs);
 	if (ret < 0 && errno != EINTR)
 		i_fatal("epoll_wait(): %m");
 
 	/* execute timeout handlers */
         io_loop_handle_timeouts(ioloop);
 
-	if (ret <= 0 || !ioloop->running) {
-		/* No events */
+	if (!ioloop->running)
 		return;
-	}
 
-	while (ret-- > 0) {
+	for (i = 0; i < ret; i++) {
+		/* io_loop_handle_add() may cause events array reallocation,
+		   so we have use array_idx() */
+		event = array_idx(&ctx->events, i);
 		list = event->data.ptr;
 
-		for (i = 0; i < IOLOOP_IOLIST_IOS_PER_FD; i++) {
-			io = list->ios[i];
+		for (j = 0; j < IOLOOP_IOLIST_IOS_PER_FD; j++) {
+			io = list->ios[j];
 			if (io == NULL)
 				continue;
 
@@ -198,7 +200,6 @@
 				}
 			}
 		}
-		event++;
 	}
 }
 
--- a/src/lib/ioloop-kqueue.c	Wed Aug 16 23:48:35 2006 +0300
+++ b/src/lib/ioloop-kqueue.c	Thu Aug 17 00:33:40 2006 +0300
@@ -145,12 +145,13 @@
 void io_loop_handler_run(struct ioloop *ioloop)
 {
 	struct ioloop_handler_context *ctx = ioloop->handler_context;
-	struct kevent *event;
+	struct kevent *events;
+	const struct kevent *event;
 	struct timeval tv;
 	struct timespec ts;
 	struct io_list *list;
 	unsigned int events_count, t_id;
-	int msecs, ret, i;
+	int msecs, ret, i, j;
 	bool call, called;
 
 	/* get the time left for next timeout task */
@@ -159,26 +160,26 @@
 	ts.tv_nsec = tv.tv_usec * 1000;
 
 	/* wait for events */
-	event = array_get_modifyable(&ctx->events, &events_count);
-	ret = kevent (ctx->kq, NULL, 0, event, events_count, &ts);
+	events = array_get_modifyable(&ctx->events, &events_count);
+	ret = kevent (ctx->kq, NULL, 0, events, events_count, &ts);
 	if (ret < 0 && errno != EINTR)
 		i_fatal("kevent(): %m");
 
 	/* execute timeout handlers */
 	io_loop_handle_timeouts(ioloop);
 
-	if (ret <= 0 || !ioloop->running) {
-		/* no I/O events */
+	if (!ioloop->running)
 		return;
-	}
 
-	/* loop through all received events */
-	while (ret-- > 0) {
+	for (i = 0; i < ret; i++) {
+		/* io_loop_handle_add() may cause events array reallocation,
+		   so we have use array_idx() */
+		event = array_idx(&ctx->events, i);
 		list = (void *)event->udata;
 
 		called = FALSE;
-		for (i = 0; i < IOLOOP_IOLIST_IOS_PER_FD; i++) {
-			struct io *io = list->ios[i];
+		for (j = 0; j < IOLOOP_IOLIST_IOS_PER_FD; j++) {
+			struct io *io = list->ios[j];
 			if (io == NULL)
 				continue;
 
@@ -217,7 +218,6 @@
 				event->fflags, (unsigned long long)event->data,
 				io_list_filter(list));
 		}
-		event++;
 	}
 }