]>
jfr.im git - irc/rqf/shadowircd.git/blob - libratbox/src/select.c
2 * ircd-ratbox: A slightly useful ircd.
3 * select.c: select() 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
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.
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.
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
26 #define FD_SETSIZE 65535
27 #include <libratbox_config.h>
28 #include <ratbox_lib.h>
29 #include <commio-int.h>
31 #if defined(HAVE_SELECT) || defined(_WIN32)
34 #define MY_FD_SET(x, y) FD_SET((SOCKET)x, y)
35 #define MY_FD_CLR(x, y) FD_CLR((SOCKET)x, y)
37 #define MY_FD_SET(x, y) FD_SET(x, y)
38 #define MY_FD_CLR(x, y) FD_CLR(x, y)
41 #ifdef HAVE_SYS_SELECT_H
42 #include <sys/select.h>
45 * Note that this is only a single list - multiple lists is kinda pointless
46 * under select because the list size is a function of the highest FD :-)
50 static fd_set select_readfds
;
51 static fd_set select_writefds
;
54 * You know, I'd rather have these local to rb_select but for some
55 * reason my gcc decides that I can't modify them at all..
58 static fd_set tmpreadfds
;
59 static fd_set tmpwritefds
;
61 static int rb_maxfd
= -1;
62 static void select_update_selectfds(rb_fde_t
*F
, short event
, PF
* handler
);
64 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
65 /* Private functions */
68 * set and clear entries in the select array ..
71 select_update_selectfds(rb_fde_t
*F
, short event
, PF
* handler
)
73 /* Update the read / write set */
74 if(event
& RB_SELECT_READ
)
78 MY_FD_SET(F
->fd
, &select_readfds
);
79 F
->pflags
|= RB_SELECT_READ
;
83 MY_FD_CLR(F
->fd
, &select_readfds
);
84 F
->pflags
&= ~RB_SELECT_READ
;
88 if(event
& RB_SELECT_WRITE
)
92 MY_FD_SET(F
->fd
, &select_writefds
);
93 F
->pflags
|= RB_SELECT_WRITE
;
97 MY_FD_CLR(F
->fd
, &select_writefds
);
98 F
->pflags
&= ~RB_SELECT_WRITE
;
102 if(F
->pflags
& (RB_SELECT_READ
| RB_SELECT_WRITE
))
109 else if(F
->fd
<= rb_maxfd
)
111 while(rb_maxfd
>= 0 && !FD_ISSET(rb_maxfd
, &select_readfds
)
112 && !FD_ISSET(rb_maxfd
, &select_writefds
))
118 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
119 /* Public functions */
122 rb_setup_fd_select(rb_fde_t
*F
)
131 * This is a needed exported function which will be called to initialise
132 * the network loop code.
134 extern int rb_maxconnections
;
136 rb_init_netio_select(void)
138 if(rb_maxconnections
> FD_SETSIZE
)
139 rb_maxconnections
= FD_SETSIZE
; /* override this */
140 FD_ZERO(&select_readfds
);
141 FD_ZERO(&select_writefds
);
148 * This is a needed exported function which will be called to register
149 * and deregister interest in a pending IO state for a given FD.
152 rb_setselect_select(rb_fde_t
*F
, unsigned int type
, PF
* handler
, void *client_data
)
154 lrb_assert(IsFDOpen(F
));
156 if(type
& RB_SELECT_READ
)
158 F
->read_handler
= handler
;
159 F
->read_data
= client_data
;
160 select_update_selectfds(F
, RB_SELECT_READ
, handler
);
162 if(type
& RB_SELECT_WRITE
)
164 F
->write_handler
= handler
;
165 F
->write_data
= client_data
;
166 select_update_selectfds(F
, RB_SELECT_WRITE
, handler
);
171 * Check all connections for new connections and input data that is to be
172 * processed. Also check for connections with data queued and whether we can
183 rb_select_select(long delay
)
191 /* Copy over the read/write sets so we don't have to rebuild em */
192 memcpy(&tmpreadfds
, &select_readfds
, sizeof(fd_set
));
193 memcpy(&tmpwritefds
, &select_writefds
, sizeof(fd_set
));
198 to
.tv_usec
= delay
* 1000;
199 num
= select(rb_maxfd
+ 1, &tmpreadfds
, &tmpwritefds
, NULL
, &to
);
202 if(rb_ignore_errno(errno
))
214 /* XXX we *could* optimise by falling out after doing num fds ... */
215 for(fd
= 0; fd
< rb_maxfd
+ 1; fd
++)
220 if(FD_ISSET(fd
, &tmpreadfds
))
222 hdl
= F
->read_handler
;
223 F
->read_handler
= NULL
;
225 hdl(F
, F
->read_data
);
229 continue; /* Read handler closed us..go on */
231 if(FD_ISSET(fd
, &tmpwritefds
))
233 hdl
= F
->write_handler
;
234 F
->write_handler
= NULL
;
236 hdl(F
, F
->write_data
);
239 if(F
->read_handler
== NULL
)
240 select_update_selectfds(F
, RB_SELECT_READ
, NULL
);
241 if(F
->write_handler
== NULL
)
242 select_update_selectfds(F
, RB_SELECT_WRITE
, NULL
);
247 #else /* select not supported..what sort of garbage is this? */
249 rb_init_netio_select(void)
255 rb_setselect_select(rb_fde_t
*F
, unsigned int type
, PF
* handler
, void *client_data
)
262 rb_select_select(long delay
)
269 rb_setup_fd_select(rb_fde_t
*F
)