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., 59 Temple Place, Suite 330, Boston, MA 02111-1307
25 * $Id: select.c 181 2006-12-18 02:56:07Z beu $
32 #if HARD_FDLIMIT_ >= FD_SETSIZE
33 #error HARD_FDLIMIT_ must be less than FD_SETSIZE(try using poll instead of select)
36 * Note that this is only a single list - multiple lists is kinda pointless
37 * under select because the list size is a function of the highest FD :-)
41 fd_set select_readfds
;
42 fd_set select_writefds
;
45 * You know, I'd rather have these local to comm_select but for some
46 * reason my gcc decides that I can't modify them at all..
52 static void select_update_selectfds(int fd
, short event
, PF
* handler
);
54 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
55 /* Private functions */
58 * set and clear entries in the select array ..
61 select_update_selectfds(int fd
, short event
, PF
* handler
)
63 /* Update the read / write set */
64 if(event
& COMM_SELECT_READ
)
67 FD_SET(fd
, &select_readfds
);
69 FD_CLR(fd
, &select_readfds
);
71 if(event
& COMM_SELECT_WRITE
)
74 FD_SET(fd
, &select_writefds
);
76 FD_CLR(fd
, &select_writefds
);
81 /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */
82 /* Public functions */
88 * This is a needed exported function which will be called to initialise
89 * the network loop code.
94 FD_ZERO(&select_readfds
);
95 FD_ZERO(&select_writefds
);
101 * This is a needed exported function which will be called to register
102 * and deregister interest in a pending IO state for a given FD.
105 comm_setselect(int fd
, fdlist_t list
, unsigned int type
, PF
* handler
,
106 void *client_data
, time_t timeout
)
108 fde_t
*F
= &fd_table
[fd
];
110 s_assert(F
->flags
.open
);
112 if(type
& COMM_SELECT_READ
)
114 F
->read_handler
= handler
;
115 F
->read_data
= client_data
;
116 select_update_selectfds(fd
, COMM_SELECT_READ
, handler
);
118 if(type
& COMM_SELECT_WRITE
)
120 F
->write_handler
= handler
;
121 F
->write_data
= client_data
;
122 select_update_selectfds(fd
, COMM_SELECT_WRITE
, handler
);
125 F
->timeout
= CurrentTime
+ (timeout
/ 1000);
129 * Check all connections for new connections and input data that is to be
130 * processed. Also check for connections with data queued and whether we can
141 comm_select(unsigned long delay
)
149 /* Copy over the read/write sets so we don't have to rebuild em */
150 memcpy(&tmpreadfds
, &select_readfds
, sizeof(fd_set
));
151 memcpy(&tmpwritefds
, &select_writefds
, sizeof(fd_set
));
156 to
.tv_usec
= delay
* 1000;
157 num
= select(highest_fd
+ 1, &tmpreadfds
, &tmpwritefds
, NULL
, &to
);
160 if(ignoreErrno(errno
))
172 /* XXX we *could* optimise by falling out after doing num fds ... */
173 for (fd
= 0; fd
< highest_fd
+ 1; fd
++)
177 if(FD_ISSET(fd
, &tmpreadfds
))
179 hdl
= F
->read_handler
;
180 F
->read_handler
= NULL
;
182 hdl(fd
, F
->read_data
);
185 if(F
->flags
.open
== 0)
186 continue; /* Read handler closed us..go on */
188 if(FD_ISSET(fd
, &tmpwritefds
))
190 hdl
= F
->write_handler
;
191 F
->write_handler
= NULL
;
193 hdl(fd
, F
->write_data
);
196 if(F
->read_handler
== NULL
)
197 select_update_selectfds(fd
, COMM_SELECT_READ
, NULL
);
198 if(F
->write_handler
== NULL
)
199 select_update_selectfds(fd
, COMM_SELECT_WRITE
, NULL
);