]>
jfr.im git - solanum.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
25 * $Id: select.c 25038 2008-01-23 16:03:08Z androsyn $
27 #include <libratbox_config.h>
28 #include <ratbox_lib.h>
29 #include <commio-int.h>
31 #if defined(HAVE_SELECT)
33 #ifdef HAVE_SYS_SELECT_H
34 #include <sys/select.h>
37 * Note that this is only a single list - multiple lists is kinda pointless
38 * under select because the list size is a function of the highest FD :-)
42 static fd_set select_readfds
;
43 static fd_set select_writefds
;
46 * You know, I'd rather have these local to rb_select but for some
47 * reason my gcc decides that I can't modify them at all..
50 static fd_set tmpreadfds
;
51 static fd_set tmpwritefds
;
53 static int rb_maxfd
= -1;
54 static void select_update_selectfds(rb_fde_t
*F
, short event
, PF
* handler
);
56 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
57 /* Private functions */
60 * set and clear entries in the select array ..
63 select_update_selectfds(rb_fde_t
*F
, short event
, PF
* handler
)
65 /* Update the read / write set */
66 if(event
& RB_SELECT_READ
)
70 FD_SET(F
->fd
, &select_readfds
);
71 F
->pflags
|= RB_SELECT_READ
;
75 FD_CLR(F
->fd
, &select_readfds
);
76 F
->pflags
&= ~RB_SELECT_READ
;
80 if(event
& RB_SELECT_WRITE
)
84 FD_SET(F
->fd
, &select_writefds
);
85 F
->pflags
|= RB_SELECT_WRITE
;
89 FD_CLR(F
->fd
, &select_writefds
);
90 F
->pflags
&= ~RB_SELECT_WRITE
;
94 if(F
->pflags
& (RB_SELECT_READ
|RB_SELECT_WRITE
))
101 else if(F
->fd
<= rb_maxfd
)
103 while(rb_maxfd
>= 0 && !FD_ISSET(rb_maxfd
, &select_readfds
) && !FD_ISSET(rb_maxfd
, &select_writefds
))
109 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
110 /* Public functions */
113 rb_setup_fd_select(rb_fde_t
*F
)
122 * This is a needed exported function which will be called to initialise
123 * the network loop code.
126 rb_init_netio_select(void)
128 FD_ZERO(&select_readfds
);
129 FD_ZERO(&select_writefds
);
136 * This is a needed exported function which will be called to register
137 * and deregister interest in a pending IO state for a given FD.
140 rb_setselect_select(rb_fde_t
*F
, unsigned int type
, PF
* handler
,
143 lrb_assert(IsFDOpen(F
));
145 if(type
& RB_SELECT_READ
)
147 F
->read_handler
= handler
;
148 F
->read_data
= client_data
;
149 select_update_selectfds(F
, RB_SELECT_READ
, handler
);
151 if(type
& RB_SELECT_WRITE
)
153 F
->write_handler
= handler
;
154 F
->write_data
= client_data
;
155 select_update_selectfds(F
, RB_SELECT_WRITE
, handler
);
160 * Check all connections for new connections and input data that is to be
161 * processed. Also check for connections with data queued and whether we can
172 rb_select_select(long delay
)
180 /* Copy over the read/write sets so we don't have to rebuild em */
181 memcpy(&tmpreadfds
, &select_readfds
, sizeof(fd_set
));
182 memcpy(&tmpwritefds
, &select_writefds
, sizeof(fd_set
));
187 to
.tv_usec
= delay
* 1000;
188 num
= select(rb_maxfd
+ 1, &tmpreadfds
, &tmpwritefds
, NULL
, &to
);
191 if(rb_ignore_errno(errno
))
203 /* XXX we *could* optimise by falling out after doing num fds ... */
204 for (fd
= 0; fd
< rb_maxfd
+ 1; fd
++)
209 if(FD_ISSET(fd
, &tmpreadfds
))
211 hdl
= F
->read_handler
;
212 F
->read_handler
= NULL
;
214 hdl(F
, F
->read_data
);
218 continue; /* Read handler closed us..go on */
220 if(FD_ISSET(fd
, &tmpwritefds
))
222 hdl
= F
->write_handler
;
223 F
->write_handler
= NULL
;
225 hdl(F
, F
->write_data
);
228 if(F
->read_handler
== NULL
)
229 select_update_selectfds(F
, RB_SELECT_READ
, NULL
);
230 if(F
->write_handler
== NULL
)
231 select_update_selectfds(F
, RB_SELECT_WRITE
, NULL
);
236 #else /* select not supported..what sort of garbage is this? */
238 rb_init_netio_select(void)
244 rb_setselect_select(rb_fde_t
*F
, unsigned int type
, PF
* handler
, void *client_data
)
251 rb_select_select(long delay
)
258 rb_setup_fd_select(rb_fde_t
*F
)