ioloop-poll.c revision d12888d64be4aa4cb8cf36ee69920a8cde58d276
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Copyright (c) 2002-2003 Timo Sirainen */
08d6658a4e2ec8104cd1307f6baa75fdb07a24f8Mark Washenberger/* @UNSAFE: whole file */
12d38e76ba7f70d6219c89ec7416fea0d5de7e02Timo Sirainenvoid io_loop_handler_init(struct ioloop *ioloop)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen p_new(ioloop->pool, struct ioloop_handler_data, 1);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen data->fds = p_new(ioloop->pool, struct pollfd, data->fds_size);
3a7113e3e2dac0e333e1a3f62af7d682896f59c6Timo Sirainen data->fd_index = p_new(ioloop->pool, int, data->idx_size);
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen memset(data->fd_index, 0xff, sizeof(int) * data->idx_size);
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainenvoid io_loop_handler_deinit(struct ioloop *ioloop)
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen p_free(ioloop->pool, ioloop->handler_data->fds);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen p_free(ioloop->pool, ioloop->handler_data->fd_index);
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen#define IO_POLL_INPUT (POLLIN|POLLPRI|POLLERR|POLLHUP|POLLNVAL)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainen#define IO_POLL_OUTPUT (POLLOUT|POLLERR|POLLHUP|POLLNVAL)
43d3ea2780b5f8557ede7b4c039e8f56cb8d357dTimo Sirainenvoid io_loop_handle_add(struct ioloop *ioloop, struct io *io)
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen struct ioloop_handler_data *data = ioloop->handler_data;
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen /* grow the fd -> index array */
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen data->idx_size = nearest_power((unsigned int) fd+1);
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen i_assert(data->idx_size < (size_t)-1 / sizeof(int));
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen data->fd_index = p_realloc(ioloop->pool, data->fd_index,
f93c833d644ecff0b0f80bee4f1cdde3e697b5c8Timo Sirainen sizeof(int) * old_size,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* grow the fd array */
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen data->fds_size = nearest_power(data->fds_size+1);
d5cebe7f98e63d4e2822863ef2faa4971e8b3a5dTimo Sirainen i_assert(data->fds_size < (size_t)-1 / sizeof(struct pollfd));
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen data->fds = p_realloc(ioloop->pool, data->fds,
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* update existing pollfd */
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* add new pollfd */
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainenvoid io_loop_handle_remove(struct ioloop *ioloop, struct io *io)
9ed2951bd0bb1878a27437d7c00611b2baadd614Timo Sirainen struct ioloop_handler_data *data = ioloop->handler_data;
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen i_assert(index >= 0 && (unsigned int) index < data->fds_size);
d6bffcdf187c155dccc04fb4267b4f82ce59347dTimo Sirainen data->fds[index].revents &= ~(POLLIN|POLLPRI);
d6bffcdf187c155dccc04fb4267b4f82ce59347dTimo Sirainen if ((data->fds[index].events & (POLLIN|POLLOUT)) == 0) {
d6bffcdf187c155dccc04fb4267b4f82ce59347dTimo Sirainen /* remove the whole pollfd */
d6bffcdf187c155dccc04fb4267b4f82ce59347dTimo Sirainen return; /* removing last one */
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen /* move the last pollfd over the removed one */
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainenvoid io_loop_handler_run(struct ioloop *ioloop)
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen struct ioloop_handler_data *data = ioloop->handler_data;
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen unsigned int t_id;
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen /* get the time left for next timeout task */
a138ac12134564b151f00fdef86fba9cd9ba8af0Timo Sirainen msecs = io_loop_get_wait_time(ioloop->timeouts, &tv, NULL);
2e29e4797a48d78d669821722bdb54fd0a1d3b94Timo Sirainen /* execute timeout handlers */
47bb4a7615c85f212f061499f04f121d6d625387Timo Sirainen /* no I/O events */
226259ee6fb9830dafc1a5ba1e95bf5a4345b406Timo Sirainen for (io = ioloop->ios; io != NULL && ret > 0; io = ioloop->next_io) {
c0757c70cfd2c9b44de3504b753a4d2f38690ef0Timo Sirainen call = (pollfd->revents & IO_POLL_INPUT) != 0;