Remove spy hooks.
[seven.git] / libseven / epoll.c
blobec22760b6f46eb6c7d64f6792dee721e5b87f8a7
1 /*
2 * ircd-ratbox: A slightly useful ircd.
3 * epoll.c: Linux epoll compatible network routines.
5 * Copyright (C) 1990 Jarkko Oikarinen and University of Oulu, Co Center
6 * Copyright (C) 1996-2002 Hybrid Development Team
7 * Copyright (C) 2001 Adrian Chadd <adrian@creative.net.au>
8 * Copyright (C) 2002-2005 ircd-ratbox development team
9 * Copyright (C) 2002 Aaron Sethman <androsyn@ratbox.org>
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
24 * USA
26 * $Id: epoll.c 181 2006-12-18 02:56:07Z beu $
29 #include "config.h"
30 #include "stdinc.h"
31 #include <sys/epoll.h>
33 #include "libseven.h"
35 static int ep; /* epoll file descriptor */
36 static struct epoll_event *pfd;
37 static int pfd_size;
40 #ifndef HAVE_EPOLL_CTL /* bah..glibc doesn't support epoll yet.. */
41 #include <sys/epoll.h>
42 #include <sys/syscall.h>
44 _syscall1(int, epoll_create, int, maxfds);
45 _syscall4(int, epoll_ctl, int, epfd, int, op, int, fd, struct epoll_event *, events);
46 _syscall4(int, epoll_wait, int, epfd, struct epoll_event *, pevents,
47 int, maxevents, int, timeout);
49 #endif /* HAVE_EPOLL_CTL */
53 * init_netio
55 * This is a needed exported function which will be called to initialise
56 * the network loop code.
58 void
59 init_netio(void)
61 pfd_size = getdtablesize();
62 ep = epoll_create(pfd_size);
63 pfd = MyMalloc(sizeof(struct epoll_event) * pfd_size);
64 if(ep < 0)
66 fprintf(stderr, "init_netio: Couldn't open epoll fd!\n");
67 exit(115); /* Whee! */
69 comm_note(ep, "epoll file descriptor");
73 * comm_setselect
75 * This is a needed exported function which will be called to register
76 * and deregister interest in a pending IO state for a given FD.
78 void
79 comm_setselect(int fd, fdlist_t list, unsigned int type, PF * handler,
80 void *client_data, time_t timeout)
82 struct epoll_event ep_event;
83 fde_t *F = &fd_table[fd];
84 int old_flags = F->pflags;
85 int op = -1;
87 s_assert(fd >= 0);
88 s_assert(F->flags.open);
90 /* Update the list, even though we're not using it .. */
91 F->list = list;
92 if(type & COMM_SELECT_READ)
94 if(handler != NULL)
95 F->pflags |= EPOLLIN;
96 else
97 F->pflags &= ~EPOLLIN;
98 F->read_handler = handler;
99 F->read_data = client_data;
102 if(type & COMM_SELECT_WRITE)
104 if(handler != NULL)
105 F->pflags |= EPOLLOUT;
106 else
107 F->pflags &= ~EPOLLOUT;
108 F->write_handler = handler;
109 F->write_data = client_data;
112 if(timeout)
113 F->timeout = CurrentTime + (timeout / 1000);
115 if(old_flags == 0 && F->pflags == 0)
116 return;
117 else if(F->pflags <= 0)
118 op = EPOLL_CTL_DEL;
119 else if(old_flags == 0 && F->pflags > 0)
120 op = EPOLL_CTL_ADD;
121 else if(F->pflags != old_flags)
122 op = EPOLL_CTL_MOD;
124 if(op == -1)
125 return;
128 ep_event.events = F->pflags;
129 ep_event.data.ptr = F;
131 if(epoll_ctl(ep, op, fd, &ep_event) != 0)
133 libseven_log("comm_setselect(): epoll_ctl failed: %s", strerror(errno));
134 abort();
141 * comm_select
143 * Called to do the new-style IO, courtesy of squid (like most of this
144 * new IO code). This routine handles the stuff we've hidden in
145 * comm_setselect and fd_table[] and calls callbacks for IO ready
146 * events.
150 comm_select(unsigned long delay)
152 int num, i, flags, old_flags, op;
153 struct epoll_event ep_event;
154 void *data;
156 num = epoll_wait(ep, pfd, pfd_size, delay);
157 set_time();
158 if(num < 0 && !ignoreErrno(errno))
160 return COMM_ERROR;
163 if(num == 0)
164 return COMM_OK;
165 for (i = 0; i < num; i++)
167 PF *hdl;
168 fde_t *F = pfd[i].data.ptr;
169 old_flags = F->pflags;
170 if(pfd[i].events & (EPOLLIN | EPOLLHUP | EPOLLERR))
172 hdl = F->read_handler;
173 data = F->read_data;
174 F->read_handler = NULL;
175 F->read_data = NULL;
176 if(hdl) {
177 hdl(F->fd, data);
179 else
180 libseven_log("epoll.c: NULL read handler called");
185 if(F->flags.open == 0)
186 continue;
187 if(pfd[i].events & (EPOLLOUT | EPOLLHUP | EPOLLERR))
189 hdl = F->write_handler;
190 data = F->write_data;
191 F->write_handler = NULL;
192 F->write_data = NULL;
194 if(hdl) {
195 hdl(F->fd, data);
197 else
198 libseven_log("epoll.c: NULL write handler called");
201 if(F->flags.open == 0)
202 continue;
204 flags = 0;
206 if(F->read_handler != NULL)
207 flags |= EPOLLIN;
208 if(F->write_handler != NULL)
209 flags |= EPOLLOUT;
211 if(old_flags != flags)
213 if(flags == 0)
214 op = EPOLL_CTL_DEL;
215 else
216 op = EPOLL_CTL_MOD;
217 F->pflags = ep_event.events = flags;
218 ep_event.data.ptr = F;
219 if(epoll_ctl(ep, op, F->fd, &ep_event) != 0)
221 libseven_log("comm_setselect(): epoll_ctl failed: %s", strerror(errno));
226 return COMM_OK;