/[svn]/ircd-hybrid-7.2/src/s_bsd_epoll.c
ViewVC logotype

Contents of /ircd-hybrid-7.2/src/s_bsd_epoll.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 966 - (show annotations)
Sat Aug 1 16:36:00 2009 UTC (10 years, 2 months ago) by michael
File MIME type: text/x-chdr
File size: 5910 byte(s)
- make valgrind shut up when calling epoll_ctl

1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * s_bsd_epoll.c: Linux epoll() compatible network routines.
4 *
5 * Copyright (C) 2002-2005 Hybrid Development Team
6 * Based also on work of Adrian Chadd, Aaron Sethman and others.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 * USA
22 *
23 * $Id$
24 */
25
26 #include "stdinc.h"
27 #if USE_IOPOLL_MECHANISM == __IOPOLL_MECHANISM_EPOLL
28 #include "fdlist.h"
29 #include "ircd.h"
30 #include "memory.h"
31 #include "s_bsd.h"
32 #include "s_log.h"
33 #include <sys/epoll.h>
34 #include <sys/syscall.h>
35
36 static fde_t efd;
37
38 /* Thanks to ircu for the following ifdefs. */
39
40 /* The GNU C library may have a valid header but stub implementations
41 * of the epoll system calls. If so, provide our own. */
42 #if defined(__stub_epoll_create) || defined(__stub___epoll_create) || defined(EPOLL_NEED_BODY)
43
44 /* Oh, did we mention that some glibc releases do not even define the
45 * syscall numbers? */
46 #if !defined(__NR_epoll_create)
47 #if defined(__ia64__)
48 #define __NR_epoll_create 1243
49 #define __NR_epoll_ctl 1244
50 #define __NR_epoll_wait 1245
51 #elif defined(__x86_64__)
52 #define __NR_epoll_create 214
53 #define __NR_epoll_ctl 233
54 #define __NR_epoll_wait 232
55 #elif defined(__sparc64__) || defined(__sparc__)
56 #define __NR_epoll_create 193
57 #define __NR_epoll_ctl 194
58 #define __NR_epoll_wait 195
59 #elif defined(__s390__) || defined(__m68k__)
60 #define __NR_epoll_create 249
61 #define __NR_epoll_ctl 250
62 #define __NR_epoll_wait 251
63 #elif defined(__ppc64__) || defined(__ppc__)
64 #define __NR_epoll_create 236
65 #define __NR_epoll_ctl 237
66 #define __NR_epoll_wait 238
67 #elif defined(__parisc__) || defined(__arm26__) || defined(__arm__)
68 #define __NR_epoll_create 224
69 #define __NR_epoll_ctl 225
70 #define __NR_epoll_wait 226
71 #elif defined(__alpha__)
72 #define __NR_epoll_create 407
73 #define __NR_epoll_ctl 408
74 #define __NR_epoll_wait 409
75 #elif defined(__sh64__)
76 #define __NR_epoll_create 282
77 #define __NR_epoll_ctl 283
78 #define __NR_epoll_wait 284
79 #elif defined(__i386__) || defined(__sh__) || defined(__m32r__) || defined(__h8300__) || defined(__frv__)
80 #define __NR_epoll_create 254
81 #define __NR_epoll_ctl 255
82 #define __NR_epoll_wait 256
83 #else /* cpu types */
84 #error No system call numbers defined for epoll family.
85 #endif /* cpu types */
86 #endif /* !defined(__NR_epoll_create) */
87
88 _syscall1(int, epoll_create, int, size)
89 _syscall4(int, epoll_ctl, int, epfd, int, op, int, fd, struct epoll_event *, event)
90 _syscall4(int, epoll_wait, int, epfd, struct epoll_event *, pevents, int, maxevents, int, timeout)
91
92 #endif /* epoll_create defined as stub */
93
94 /*
95 * init_netio
96 *
97 * This is a needed exported function which will be called to initialise
98 * the network loop code.
99 */
100 void
101 init_netio(void)
102 {
103 int fd;
104
105 if ((fd = epoll_create(hard_fdlimit)) < 0)
106 {
107 ilog(L_CRIT, "init_netio: Couldn't open epoll fd - %d: %s",
108 errno, strerror(errno));
109 exit(115); /* Whee! */
110 }
111
112 fd_open(&efd, fd, 0, "epoll file descriptor");
113 }
114
115 /*
116 * comm_setselect
117 *
118 * This is a needed exported function which will be called to register
119 * and deregister interest in a pending IO state for a given FD.
120 */
121 void
122 comm_setselect(fde_t *F, unsigned int type, PF *handler,
123 void *client_data, time_t timeout)
124 {
125 int new_events, op;
126 struct epoll_event ep_event = { 0, { 0 } };
127
128 if ((type & COMM_SELECT_READ))
129 {
130 F->read_handler = handler;
131 F->read_data = client_data;
132 }
133
134 if ((type & COMM_SELECT_WRITE))
135 {
136 F->write_handler = handler;
137 F->write_data = client_data;
138 }
139
140 new_events = (F->read_handler ? EPOLLIN : 0) |
141 (F->write_handler ? EPOLLOUT : 0);
142
143 if (timeout != 0)
144 F->timeout = CurrentTime + (timeout / 1000);
145
146 if (new_events != F->evcache)
147 {
148 if (new_events == 0)
149 op = EPOLL_CTL_DEL;
150 else if (F->evcache == 0)
151 op = EPOLL_CTL_ADD;
152 else
153 op = EPOLL_CTL_MOD;
154
155 ep_event.events = F->evcache = new_events;
156 ep_event.data.fd = F->fd;
157
158 if (epoll_ctl(efd.fd, op, F->fd, &ep_event) != 0)
159 {
160 ilog(L_CRIT, "comm_setselect: epoll_ctl() failed: %s", strerror(errno));
161 abort();
162 }
163 }
164 }
165
166 /*
167 * comm_select()
168 *
169 * Called to do the new-style IO, courtesy of of squid (like most of this
170 * new IO code). This routine handles the stuff we've hidden in
171 * comm_setselect and fd_table[] and calls callbacks for IO ready
172 * events.
173 */
174 void
175 comm_select(void)
176 {
177 struct epoll_event ep_fdlist[128];
178 int num, i;
179 PF *hdl;
180 fde_t *F;
181
182 num = epoll_wait(efd.fd, ep_fdlist, 128, SELECT_DELAY);
183
184 set_time();
185
186 if (num < 0)
187 {
188 #ifdef HAVE_USLEEP
189 usleep(50000); /* avoid 99% CPU in comm_select */
190 #endif
191 return;
192 }
193
194 for (i = 0; i < num; i++)
195 {
196 F = lookup_fd(ep_fdlist[i].data.fd);
197 if (F == NULL || !F->flags.open)
198 continue;
199
200 if ((ep_fdlist[i].events & (EPOLLIN | EPOLLHUP | EPOLLERR)))
201 if ((hdl = F->read_handler) != NULL)
202 {
203 F->read_handler = NULL;
204 hdl(F, F->read_data);
205 if (!F->flags.open)
206 continue;
207 }
208
209 if ((ep_fdlist[i].events & (EPOLLOUT | EPOLLHUP | EPOLLERR)))
210 if ((hdl = F->write_handler) != NULL)
211 {
212 F->write_handler = NULL;
213 hdl(F, F->write_data);
214 if (!F->flags.open)
215 continue;
216 }
217
218 comm_setselect(F, 0, NULL, NULL, 0);
219 }
220 }
221 #endif

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.26