]>
jfr.im git - solanum.git/blob - librb/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
27 #define FD_SETSIZE 65535
28 #include <librb_config.h>
30 #include <commio-int.h>
32 #if defined(HAVE_SELECT) || defined(_WIN32)
35 #define MY_FD_SET(x, y) FD_SET((SOCKET)x, y)
36 #define MY_FD_CLR(x, y) FD_CLR((SOCKET)x, y)
38 #define MY_FD_SET(x, y) FD_SET(x, y)
39 #define MY_FD_CLR(x, y) FD_CLR(x, y)
42 #ifdef HAVE_SYS_SELECT_H
43 #include <sys/select.h>
46 * Note that this is only a single list - multiple lists is kinda pointless
47 * under select because the list size is a function of the highest FD :-)
51 static fd_set select_readfds
;
52 static fd_set select_writefds
;
55 * You know, I'd rather have these local to rb_select but for some
56 * reason my gcc decides that I can't modify them at all..
59 static fd_set tmpreadfds
;
60 static fd_set tmpwritefds
;
62 static int rb_maxfd
= -1;
63 static void select_update_selectfds(rb_fde_t
*F
, short event
, PF
* handler
);
65 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
66 /* Private functions */
69 * set and clear entries in the select array ..
72 select_update_selectfds(rb_fde_t
*F
, short event
, PF
* handler
)
74 /* Update the read / write set */
75 if(event
& RB_SELECT_READ
)
79 MY_FD_SET(F
->fd
, &select_readfds
);
80 F
->pflags
|= RB_SELECT_READ
;
84 MY_FD_CLR(F
->fd
, &select_readfds
);
85 F
->pflags
&= ~RB_SELECT_READ
;
89 if(event
& RB_SELECT_WRITE
)
93 MY_FD_SET(F
->fd
, &select_writefds
);
94 F
->pflags
|= RB_SELECT_WRITE
;
98 MY_FD_CLR(F
->fd
, &select_writefds
);
99 F
->pflags
&= ~RB_SELECT_WRITE
;
103 if(F
->pflags
& (RB_SELECT_READ
| RB_SELECT_WRITE
))
110 else if(F
->fd
<= rb_maxfd
)
112 while(rb_maxfd
>= 0 && !FD_ISSET(rb_maxfd
, &select_readfds
)
113 && !FD_ISSET(rb_maxfd
, &select_writefds
))
119 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
120 /* Public functions */
123 rb_setup_fd_select(rb_fde_t
*F
__attribute__((unused
)))
132 * This is a needed exported function which will be called to initialise
133 * the network loop code.
135 extern int rb_maxconnections
;
137 rb_init_netio_select(void)
139 if(rb_maxconnections
> FD_SETSIZE
)
140 rb_maxconnections
= FD_SETSIZE
; /* override this */
141 FD_ZERO(&select_readfds
);
142 FD_ZERO(&select_writefds
);
149 * This is a needed exported function which will be called to register
150 * and deregister interest in a pending IO state for a given FD.
153 rb_setselect_select(rb_fde_t
*F
, unsigned int type
, PF
* handler
, void *client_data
)
155 lrb_assert(IsFDOpen(F
));
157 if(type
& RB_SELECT_READ
)
159 F
->read_handler
= handler
;
160 F
->read_data
= client_data
;
161 select_update_selectfds(F
, RB_SELECT_READ
, handler
);
163 if(type
& RB_SELECT_WRITE
)
165 F
->write_handler
= handler
;
166 F
->write_data
= client_data
;
167 select_update_selectfds(F
, RB_SELECT_WRITE
, handler
);
172 * Check all connections for new connections and input data that is to be
173 * processed. Also check for connections with data queued and whether we can
184 rb_select_select(long delay
)
192 /* Copy over the read/write sets so we don't have to rebuild em */
193 memcpy(&tmpreadfds
, &select_readfds
, sizeof(fd_set
));
194 memcpy(&tmpwritefds
, &select_writefds
, sizeof(fd_set
));
199 to
.tv_usec
= delay
* 1000;
200 num
= select(rb_maxfd
+ 1, &tmpreadfds
, &tmpwritefds
, NULL
, &to
);
203 if(rb_ignore_errno(errno
))
215 /* XXX we *could* optimise by falling out after doing num fds ... */
216 for(fd
= 0; fd
< rb_maxfd
+ 1; fd
++)
221 if(FD_ISSET(fd
, &tmpreadfds
))
223 hdl
= F
->read_handler
;
224 F
->read_handler
= NULL
;
226 hdl(F
, F
->read_data
);
230 continue; /* Read handler closed us..go on */
232 if(FD_ISSET(fd
, &tmpwritefds
))
234 hdl
= F
->write_handler
;
235 F
->write_handler
= NULL
;
237 hdl(F
, F
->write_data
);
240 if(F
->read_handler
== NULL
)
241 select_update_selectfds(F
, RB_SELECT_READ
, NULL
);
242 if(F
->write_handler
== NULL
)
243 select_update_selectfds(F
, RB_SELECT_WRITE
, NULL
);
248 #else /* select not supported..what sort of garbage is this? */
250 rb_init_netio_select(void)
256 rb_setselect_select(rb_fde_t
*F
__attribute__((unused
)), unsigned int type
__attribute__((unused
)), PF
* handler
__attribute__((unused
)), void *client_data
__attribute__((unused
)))
263 rb_select_select(long delay
__attribute__((unused
)))
270 rb_setup_fd_select(rb_fde_t
*F
__attribute__((unused
)))