]> jfr.im git - solanum.git/blob - librb/src/poll.c
Revert "Accept expired certificates"
[solanum.git] / librb / src / poll.c
1 /*
2 * ircd-ratbox: A slightly useful ircd.
3 * s_bsd_poll.c: POSIX poll() compatible network routines.
4 *
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 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
23 * USA
24 *
25 */
26 #include <librb_config.h>
27 #include <rb_lib.h>
28 #include <commio-int.h>
29 #include <poll.h>
30
31 #ifdef HAVE_SYS_POLL_H
32 #include <sys/poll.h>
33 #endif
34
35
36 /* I hate linux -- adrian */
37 #ifndef POLLRDNORM
38 #define POLLRDNORM POLLIN
39 #endif
40 #ifndef POLLWRNORM
41 #define POLLWRNORM POLLOUT
42 #endif
43
44 struct _pollfd_list
45 {
46 struct pollfd *pollfds;
47 int maxindex; /* highest FD number */
48 int allocated; /* number of pollfds allocated */
49 };
50
51 typedef struct _pollfd_list pollfd_list_t;
52
53 static pollfd_list_t pollfd_list;
54
55 int
56 rb_setup_fd_poll(rb_fde_t *F __attribute__((unused)))
57 {
58 return 0;
59 }
60
61
62 /*
63 * rb_init_netio
64 *
65 * This is a needed exported function which will be called to initialise
66 * the network loop code.
67 */
68 int
69 rb_init_netio_poll(void)
70 {
71 int fd;
72 pollfd_list.pollfds = rb_malloc(rb_getmaxconnect() * (sizeof(struct pollfd)));
73 pollfd_list.allocated = rb_getmaxconnect();
74 for(fd = 0; fd < rb_getmaxconnect(); fd++)
75 {
76 pollfd_list.pollfds[fd].fd = -1;
77 }
78 pollfd_list.maxindex = 0;
79 return 0;
80 }
81
82 static void
83 resize_pollarray(int fd)
84 {
85 if(rb_unlikely(fd >= pollfd_list.allocated))
86 {
87 int x, old_value = pollfd_list.allocated;
88 pollfd_list.allocated += 1024;
89 pollfd_list.pollfds =
90 rb_realloc(pollfd_list.pollfds,
91 pollfd_list.allocated * (sizeof(struct pollfd)));
92 memset(&pollfd_list.pollfds[old_value + 1], 0, sizeof(struct pollfd) * 1024);
93 for(x = old_value + 1; x < pollfd_list.allocated; x++)
94 {
95 pollfd_list.pollfds[x].fd = -1;
96 }
97 }
98 }
99
100 /*
101 * rb_setselect
102 *
103 * This is a needed exported function which will be called to register
104 * and deregister interest in a pending IO state for a given FD.
105 */
106 void
107 rb_setselect_poll(rb_fde_t *F, unsigned int type, PF * handler, void *client_data)
108 {
109 if(F == NULL)
110 return;
111
112 if(type & RB_SELECT_READ)
113 {
114 F->read_handler = handler;
115 F->read_data = client_data;
116 if(handler != NULL)
117 F->pflags |= POLLRDNORM;
118 else
119 F->pflags &= ~POLLRDNORM;
120 }
121 if(type & RB_SELECT_WRITE)
122 {
123 F->write_handler = handler;
124 F->write_data = client_data;
125 if(handler != NULL)
126 F->pflags |= POLLWRNORM;
127 else
128 F->pflags &= ~POLLWRNORM;
129 }
130 resize_pollarray(F->fd);
131
132 if(F->pflags <= 0)
133 {
134 pollfd_list.pollfds[F->fd].events = 0;
135 pollfd_list.pollfds[F->fd].fd = -1;
136 if(F->fd == pollfd_list.maxindex)
137 {
138 while(pollfd_list.maxindex >= 0
139 && pollfd_list.pollfds[pollfd_list.maxindex].fd == -1)
140 pollfd_list.maxindex--;
141 }
142 }
143 else
144 {
145 pollfd_list.pollfds[F->fd].events = F->pflags;
146 pollfd_list.pollfds[F->fd].fd = F->fd;
147 if(F->fd > pollfd_list.maxindex)
148 pollfd_list.maxindex = F->fd;
149 }
150
151 }
152
153 /* int rb_select(unsigned long delay)
154 * Input: The maximum time to delay.
155 * Output: Returns -1 on error, 0 on success.
156 * Side-effects: Deregisters future interest in IO and calls the handlers
157 * if an event occurs for an FD.
158 * Comments: Check all connections for new connections and input data
159 * that is to be processed. Also check for connections with data queued
160 * and whether we can write it out.
161 * Called to do the new-style IO, courtesy of squid (like most of this
162 * new IO code). This routine handles the stuff we've hidden in
163 * rb_setselect and fd_table[] and calls callbacks for IO ready
164 * events.
165 */
166
167 int
168 rb_select_poll(long delay)
169 {
170 int num;
171 int fd;
172 int ci;
173 PF *hdl;
174 void *data;
175 struct pollfd *pfd;
176 int revents;
177
178 num = poll(pollfd_list.pollfds, pollfd_list.maxindex + 1, delay);
179 rb_set_time();
180 if(num < 0)
181 {
182 if(!rb_ignore_errno(errno))
183 return RB_OK;
184 else
185 return RB_ERROR;
186 }
187 if(num == 0)
188 return RB_OK;
189
190 /* XXX we *could* optimise by falling out after doing num fds ... */
191 for(ci = 0; ci < pollfd_list.maxindex + 1; ci++)
192 {
193 rb_fde_t *F;
194 pfd = &pollfd_list.pollfds[ci];
195
196 revents = pfd->revents;
197 fd = pfd->fd;
198 if(revents == 0 || fd == -1)
199 continue;
200
201 F = rb_find_fd(fd);
202 if(F == NULL)
203 continue;
204
205 if(revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
206 {
207 hdl = F->read_handler;
208 data = F->read_data;
209 F->read_handler = NULL;
210 F->read_data = NULL;
211 if(hdl)
212 hdl(F, data);
213 }
214
215 if(IsFDOpen(F) && (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR)))
216 {
217 hdl = F->write_handler;
218 data = F->write_data;
219 F->write_handler = NULL;
220 F->write_data = NULL;
221 if(hdl)
222 hdl(F, data);
223 }
224
225 if(F->read_handler == NULL)
226 rb_setselect_poll(F, RB_SELECT_READ, NULL, NULL);
227 if(F->write_handler == NULL)
228 rb_setselect_poll(F, RB_SELECT_WRITE, NULL, NULL);
229
230 }
231 return 0;
232 }