/[svn]/ircd-hybrid/trunk/src/s_bsd_poll.c
ViewVC logotype

Contents of /ircd-hybrid/trunk/src/s_bsd_poll.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2725 - (show annotations)
Sun Dec 29 13:01:00 2013 UTC (8 years, 11 months ago) by michael
File MIME type: text/x-chdr
File size: 4729 byte(s)
- Fixed bug where ircd didn't timeout SSL connections that haven't
  finished the SSL handshake. Reported by Adam.

1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * s_bsd_poll.c: POSIX poll() compatible network routines.
4 *
5 * Originally by Adrian Chadd <adrian@creative.net.au>
6 * Copyright (C) 2002 Hybrid Development Team
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_POLL
28 #include <sys/poll.h>
29 #include "fdlist.h"
30 #include "list.h"
31 #include "memory.h"
32 #include "hook.h"
33 #include "ircd.h"
34 #include "s_bsd.h"
35 #include "log.h"
36
37 /* I hate linux -- adrian */
38 #ifndef POLLRDNORM
39 #define POLLRDNORM POLLIN
40 #endif
41 #ifndef POLLWRNORM
42 #define POLLWRNORM POLLOUT
43 #endif
44
45 static struct pollfd *pollfds;
46 static int pollmax = -1; /* highest FD number */
47
48
49 /*
50 * init_netio
51 *
52 * This is a needed exported function which will be called to initialise
53 * the network loop code.
54 */
55 void
56 init_netio(void)
57 {
58 int fd;
59
60 pollfds = MyMalloc(sizeof(struct pollfd) * hard_fdlimit);
61
62 for (fd = 0; fd < hard_fdlimit; fd++)
63 pollfds[fd].fd = -1;
64 }
65
66 /*
67 * find a spare slot in the fd list. We can optimise this out later!
68 * -- adrian
69 */
70 static inline int
71 poll_findslot(void)
72 {
73 int i;
74
75 for (i = 0; i < hard_fdlimit; i++)
76 if (pollfds[i].fd == -1)
77 {
78 /* MATCH!!#$*&$ */
79 return i;
80 }
81
82 assert(1 == 0);
83 /* NOTREACHED */
84 return -1;
85 }
86
87 /*
88 * comm_setselect
89 *
90 * This is a needed exported function which will be called to register
91 * and deregister interest in a pending IO state for a given FD.
92 */
93 void
94 comm_setselect(fde_t *F, unsigned int type, PF *handler,
95 void *client_data, time_t timeout)
96 {
97 int new_events;
98
99 if ((type & COMM_SELECT_READ))
100 {
101 F->read_handler = handler;
102 F->read_data = client_data;
103 }
104
105 if ((type & COMM_SELECT_WRITE))
106 {
107 F->write_handler = handler;
108 F->write_data = client_data;
109 }
110
111 new_events = (F->read_handler ? POLLRDNORM : 0) |
112 (F->write_handler ? POLLWRNORM : 0);
113
114 if (timeout != 0)
115 {
116 F->timeout = CurrentTime + (timeout / 1000);
117 F->timeout_handler = handler;
118 F->timeout_data = client_data;
119 }
120
121 if (new_events != F->evcache)
122 {
123 if (new_events == 0)
124 {
125 pollfds[F->comm_index].fd = -1;
126 pollfds[F->comm_index].revents = 0;
127
128 if (pollmax == F->comm_index)
129 while (pollmax >= 0 && pollfds[pollmax].fd == -1)
130 pollmax--;
131 }
132 else
133 {
134 if (F->evcache == 0)
135 {
136 F->comm_index = poll_findslot();
137 if (F->comm_index > pollmax)
138 pollmax = F->comm_index;
139
140 pollfds[F->comm_index].fd = F->fd;
141 }
142
143 pollfds[F->comm_index].events = new_events;
144 pollfds[F->comm_index].revents = 0;
145 }
146
147 F->evcache = new_events;
148 }
149 }
150
151 /*
152 * comm_select
153 *
154 * Called to do the new-style IO, courtesy of of squid (like most of this
155 * new IO code). This routine handles the stuff we've hidden in
156 * comm_setselect and fd_table[] and calls callbacks for IO ready
157 * events.
158 */
159 void
160 comm_select(void)
161 {
162 int num, ci, revents;
163 PF *hdl;
164 fde_t *F;
165
166 /* XXX kill that +1 later ! -- adrian */
167 num = poll(pollfds, pollmax + 1, SELECT_DELAY);
168
169 set_time();
170
171 if (num < 0)
172 {
173 #ifdef HAVE_USLEEP
174 usleep(50000); /* avoid 99% CPU in comm_select */
175 #endif
176 return;
177 }
178
179 for (ci = 0; ci <= pollmax && num > 0; ci++)
180 {
181 if ((revents = pollfds[ci].revents) == 0 || pollfds[ci].fd == -1)
182 continue;
183 num--;
184
185 F = lookup_fd(pollfds[ci].fd);
186 if (F == NULL || !F->flags.open)
187 continue;
188
189 if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
190 {
191 if ((hdl = F->read_handler) != NULL)
192 {
193 F->read_handler = NULL;
194 hdl(F, F->read_data);
195 if (!F->flags.open)
196 continue;
197 }
198 }
199
200 if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR))
201 {
202 if ((hdl = F->write_handler) != NULL)
203 {
204 F->write_handler = NULL;
205 hdl(F, F->write_data);
206 if (!F->flags.open)
207 continue;
208 }
209 }
210
211 comm_setselect(F, 0, NULL, NULL, 0);
212 }
213 }
214 #endif

Properties

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

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