/[svn]/ircd-hybrid-7.2/src/s_bsd_select.c
ViewVC logotype

Contents of /ircd-hybrid-7.2/src/s_bsd_select.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 908 - (show annotations)
Sun Nov 4 23:21:51 2007 UTC (13 years, 3 months ago) by stu
File MIME type: text/x-chdr
File size: 4860 byte(s)
Completely redo the build system.  Now uses libtool and automake.  Suggest you clean out your tree and then do ./autogen.sh.
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * s_bsd_select.c: select() compatible network routines.
4 *
5 * Originally by Adrian Chadd <adrian@creative.net.au>
6 * Copyright (C) 2002 Hybrid Development Team
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 * USA
22 *
23 * $Id$
24 */
25
26 #include "stdinc.h"
27 #if USE_IOPOLL_MECHANISM == __IOPOLL_MECHANISM_SELECT
28 #include "fdlist.h"
29 #include "hook.h"
30 #include "ircd.h"
31 #include "s_bsd.h"
32 #include "s_log.h"
33
34 /*
35 * Note that this is only a single list - multiple lists is kinda pointless
36 * under select because the list size is a function of the highest FD :-)
37 * -- adrian
38 */
39
40 static fd_set select_readfds, tmpreadfds;
41 static fd_set select_writefds, tmpwritefds;
42 static int highest_fd = -1;
43 static dlink_node *hookptr;
44
45 /*
46 * changing_fdlimit
47 *
48 * Make sure hard_fdlimit doesn't go too big.
49 */
50 static void *
51 changing_fdlimit(va_list args)
52 {
53 int fdmax = va_arg(args, int);
54
55 if (fdmax > FD_SETSIZE)
56 fdmax = FD_SETSIZE;
57
58 return pass_callback(hookptr, fdmax);
59 }
60
61 /*
62 * init_netio
63 *
64 * This is a needed exported function which will be called to initialise
65 * the network loop code.
66 */
67 void
68 init_netio(void)
69 {
70 FD_ZERO(&select_readfds);
71 FD_ZERO(&select_writefds);
72
73 hookptr = install_hook(fdlimit_cb, changing_fdlimit);
74 }
75
76 /*
77 * comm_setselect
78 *
79 * This is a needed exported function which will be called to register
80 * and deregister interest in a pending IO state for a given FD.
81 */
82 void
83 comm_setselect(fde_t *F, unsigned int type, PF *handler,
84 void *client_data, time_t timeout)
85 {
86 int new_events;
87
88 if ((type & COMM_SELECT_READ))
89 {
90 F->read_handler = handler;
91 F->read_data = client_data;
92 }
93
94 if ((type & COMM_SELECT_WRITE))
95 {
96 F->write_handler = handler;
97 F->write_data = client_data;
98 }
99
100 new_events = (F->read_handler ? COMM_SELECT_READ : 0) |
101 (F->write_handler ? COMM_SELECT_WRITE : 0);
102
103 if (timeout != 0)
104 F->timeout = CurrentTime + (timeout / 1000);
105
106 if (new_events != F->evcache)
107 {
108 if ((new_events & COMM_SELECT_READ))
109 FD_SET(F->fd, &select_readfds);
110 else
111 {
112 FD_CLR(F->fd, &select_readfds);
113 FD_CLR(F->fd, &tmpreadfds);
114 }
115
116 if ((new_events & COMM_SELECT_WRITE))
117 FD_SET(F->fd, &select_writefds);
118 else
119 {
120 FD_CLR(F->fd, &select_writefds);
121 FD_CLR(F->fd, &tmpwritefds);
122 }
123
124 if (new_events == 0)
125 {
126 if (highest_fd == F->fd)
127 while (highest_fd >= 0 && (FD_ISSET(highest_fd, &select_readfds) ||
128 FD_ISSET(highest_fd, &select_writefds)))
129 highest_fd--;
130 }
131 else if (F->evcache == 0)
132 if (F->fd > highest_fd)
133 highest_fd = F->fd;
134
135 F->evcache = new_events;
136 }
137 }
138
139 /*
140 * comm_select
141 *
142 * Called to do the new-style IO, courtesy of squid (like most of this
143 * new IO code). This routine handles the stuff we've hidden in
144 * comm_setselect and fd_table[] and calls callbacks for IO ready
145 * events.
146 */
147 void
148 comm_select(void)
149 {
150 struct timeval to;
151 int num, fd;
152 fde_t *F;
153 PF *hdl;
154
155 /* Copy over the read/write sets so we don't have to rebuild em */
156 memcpy(&tmpreadfds, &select_readfds, sizeof(fd_set));
157 memcpy(&tmpwritefds, &select_writefds, sizeof(fd_set));
158
159 to.tv_sec = 0;
160 to.tv_usec = SELECT_DELAY * 1000;
161 num = select(highest_fd + 1, &tmpreadfds, &tmpwritefds, NULL, &to);
162
163 set_time();
164
165 if (num < 0)
166 {
167 #ifdef HAVE_USLEEP
168 usleep(50000);
169 #endif
170 return;
171 }
172
173 for (fd = 0; fd <= highest_fd && num > 0; fd++)
174 if (FD_ISSET(fd, &tmpreadfds) || FD_ISSET(fd, &tmpwritefds))
175 {
176 num--;
177
178 F = lookup_fd(fd);
179 if (F == NULL || !F->flags.open)
180 continue;
181
182 if (FD_ISSET(fd, &tmpreadfds))
183 if ((hdl = F->read_handler) != NULL)
184 {
185 F->read_handler = NULL;
186 hdl(F, F->read_data);
187 if (!F->flags.open)
188 continue;
189 }
190
191 if (FD_ISSET(fd, &tmpwritefds))
192 if ((hdl = F->write_handler) != NULL)
193 {
194 F->write_handler = NULL;
195 hdl(F, F->write_data);
196 if (!F->flags.open)
197 continue;
198 }
199
200 comm_setselect(F, 0, NULL, NULL, 0);
201 }
202 }
203 #endif

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision

svnadmin@ircd-hybrid.org
ViewVC Help
Powered by ViewVC 1.1.28