/*
- * ircd-ratbox: A slightly useful ircd.
+ * charybdis: A slightly useful ircd.
* epoll.c: Linux epoll compatible network routines.
*
* Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
* Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
* Copyright (C) 2002-2005 ircd-ratbox development team
* Copyright (C) 2002 Aaron Sethman <androsyn@ratbox.org>
+ * Copyright (C) 2008 William Pitcock <nenolod@sacredspiral.co.uk>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
* USA
*
- * $Id: epoll.c 390 2005-12-07 18:46:56Z nenolod $
+ * $Id: epoll.c 3444 2007-05-09 00:32:08Z nenolod $
*/
#include "config.h"
void *client_data, time_t timeout)
{
struct epoll_event ep_event;
- fde_t *F = &fd_table[fd];
+ fde_t *F = comm_locate_fd(fd);
int old_flags = F->pflags;
int op = -1;
libcharybdis_log("comm_setselect(): epoll_ctl failed: %s", strerror(errno));
abort();
}
-
-
}
/*
}
else
libcharybdis_log("epoll.c: NULL read handler called");
-
}
- if(F->flags.open == 0)
+ if(F->flags.open == 0 && F->pflags == 0)
continue;
+ else if (F->flags.open == 0)
+ {
+ F->pflags = ep_event.events = flags;
+ ep_event.data.ptr = F;
+
+ if(epoll_ctl(ep, EPOLL_CTL_DEL, F->fd, &ep_event) != 0) {
+ /* XXX: we assume this is because close(2) has been called here. */
+ if (errno == EBADF)
+ continue;
+
+ libcharybdis_log("comm_select(): epoll_ctl failed while trying to delete an FD marked as closed: %s", strerror(errno));
+ abort();
+ }
+
+ continue;
+ }
+
if(pfd[i].events & (EPOLLOUT | EPOLLHUP | EPOLLERR))
{
hdl = F->write_handler;
libcharybdis_log("epoll.c: NULL write handler called");
}
- if(F->flags.open == 0)
- continue;
+ if(F->flags.open == 0 && F->pflags == 0)
+ continue;
+ else if (F->flags.open == 0)
+ {
+ F->pflags = ep_event.events = flags;
+ ep_event.data.ptr = F;
+
+ if(epoll_ctl(ep, EPOLL_CTL_DEL, F->fd, &ep_event) != 0) {
+ /* XXX: we assume this is because close(2) has been called here. */
+ if (errno == EBADF)
+ continue;
+
+ libcharybdis_log("comm_select(): epoll_ctl failed while trying to delete an FD marked as closed: %s", strerror(errno));
+ abort();
+ }
+
+ continue;
+ }
flags = 0;
if(F->read_handler != NULL)
flags |= EPOLLIN;
+ else
+ flags &= ~EPOLLIN;
+
if(F->write_handler != NULL)
flags |= EPOLLOUT;
+ else
+ flags &= ~EPOLLOUT;
if(old_flags != flags)
{
op = EPOLL_CTL_DEL;
else
op = EPOLL_CTL_MOD;
+
F->pflags = ep_event.events = flags;
ep_event.data.ptr = F;
+
if(epoll_ctl(ep, op, F->fd, &ep_event) != 0)
- {
- libcharybdis_log("comm_setselect(): epoll_ctl failed: %s", strerror(errno));
- }
+ libcharybdis_log("comm_select(): epoll_ctl failed: %s", strerror(errno));
}
}
return COMM_OK;
}
-