]> jfr.im git - solanum.git/blame - librb/src/poll.c
Revert "Accept expired certificates"
[solanum.git] / librb / src / poll.c
CommitLineData
db137867
AC
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 *
db137867 25 */
fe037171
EM
26#include <librb_config.h>
27#include <rb_lib.h>
db137867 28#include <commio-int.h>
3c586ccf 29#include <poll.h>
db137867 30
3c586ccf 31#ifdef HAVE_SYS_POLL_H
db137867 32#include <sys/poll.h>
3c586ccf 33#endif
db137867
AC
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
44struct _pollfd_list
45{
46 struct pollfd *pollfds;
47 int maxindex; /* highest FD number */
48 int allocated; /* number of pollfds allocated */
49};
50
51typedef struct _pollfd_list pollfd_list_t;
52
53static pollfd_list_t pollfd_list;
54
55int
8679c0fe 56rb_setup_fd_poll(rb_fde_t *F __attribute__((unused)))
db137867
AC
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 */
68int
69rb_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();
3202e249 74 for(fd = 0; fd < rb_getmaxconnect(); fd++)
db137867
AC
75 {
76 pollfd_list.pollfds[fd].fd = -1;
77 }
78 pollfd_list.maxindex = 0;
79 return 0;
80}
81
82static void
83resize_pollarray(int fd)
84{
c2ac22cc 85 if(rb_unlikely(fd >= pollfd_list.allocated))
db137867
AC
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);
3202e249 93 for(x = old_value + 1; x < pollfd_list.allocated; x++)
db137867
AC
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 */
106void
3202e249 107rb_setselect_poll(rb_fde_t *F, unsigned int type, PF * handler, void *client_data)
db137867
AC
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 {
3202e249
VY
138 while(pollfd_list.maxindex >= 0
139 && pollfd_list.pollfds[pollfd_list.maxindex].fd == -1)
db137867
AC
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
167int
168rb_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);
3202e249 179 rb_set_time();
db137867
AC
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)
3202e249
VY
188 return RB_OK;
189
db137867 190 /* XXX we *could* optimise by falling out after doing num fds ... */
3202e249 191 for(ci = 0; ci < pollfd_list.maxindex + 1; ci++)
db137867
AC
192 {
193 rb_fde_t *F;
194 pfd = &pollfd_list.pollfds[ci];
195
196 revents = pfd->revents;
3202e249 197 fd = pfd->fd;
db137867
AC
198 if(revents == 0 || fd == -1)
199 continue;
200
201 F = rb_find_fd(fd);
202 if(F == NULL)
203 continue;
3202e249 204
db137867
AC
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;
3202e249 221 if(hdl)
db137867
AC
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);
3202e249 229
db137867
AC
230 }
231 return 0;
232}