ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/s_bsd_select.c
Revision: 1592
Committed: Sat Oct 27 21:02:32 2012 UTC (11 years, 5 months ago) by michael
Content type: text/x-csrc
File size: 4876 byte(s)
Log Message:
- Second time's the charm? Moving svnroot/ircd-hybrid-8 to
  svnroot/ircd-hybrid/trunk

File Contents

# Content
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 "list.h"
29 #include "fdlist.h"
30 #include "hook.h"
31 #include "ircd.h"
32 #include "s_bsd.h"
33 #include "log.h"
34
35 /*
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 :-)
38 * -- adrian
39 */
40
41 static fd_set select_readfds, tmpreadfds;
42 static fd_set select_writefds, tmpwritefds;
43 static int highest_fd = -1;
44 static dlink_node *hookptr;
45
46 /*
47 * changing_fdlimit
48 *
49 * Make sure hard_fdlimit doesn't go too big.
50 */
51 static void *
52 changing_fdlimit(va_list args)
53 {
54 int fdmax = va_arg(args, int);
55
56 if (fdmax > FD_SETSIZE)
57 fdmax = FD_SETSIZE;
58
59 return pass_callback(hookptr, fdmax);
60 }
61
62 /*
63 * init_netio
64 *
65 * This is a needed exported function which will be called to initialise
66 * the network loop code.
67 */
68 void
69 init_netio(void)
70 {
71 FD_ZERO(&select_readfds);
72 FD_ZERO(&select_writefds);
73
74 hookptr = install_hook(fdlimit_cb, changing_fdlimit);
75 }
76
77 /*
78 * comm_setselect
79 *
80 * This is a needed exported function which will be called to register
81 * and deregister interest in a pending IO state for a given FD.
82 */
83 void
84 comm_setselect(fde_t *F, unsigned int type, PF *handler,
85 void *client_data, time_t timeout)
86 {
87 int new_events;
88
89 if ((type & COMM_SELECT_READ))
90 {
91 F->read_handler = handler;
92 F->read_data = client_data;
93 }
94
95 if ((type & COMM_SELECT_WRITE))
96 {
97 F->write_handler = handler;
98 F->write_data = client_data;
99 }
100
101 new_events = (F->read_handler ? COMM_SELECT_READ : 0) |
102 (F->write_handler ? COMM_SELECT_WRITE : 0);
103
104 if (timeout != 0)
105 F->timeout = CurrentTime + (timeout / 1000);
106
107 if (new_events != F->evcache)
108 {
109 if ((new_events & COMM_SELECT_READ))
110 FD_SET(F->fd, &select_readfds);
111 else
112 {
113 FD_CLR(F->fd, &select_readfds);
114 FD_CLR(F->fd, &tmpreadfds);
115 }
116
117 if ((new_events & COMM_SELECT_WRITE))
118 FD_SET(F->fd, &select_writefds);
119 else
120 {
121 FD_CLR(F->fd, &select_writefds);
122 FD_CLR(F->fd, &tmpwritefds);
123 }
124
125 if (new_events == 0)
126 {
127 if (highest_fd == F->fd)
128 while (highest_fd >= 0 && (FD_ISSET(highest_fd, &select_readfds) ||
129 FD_ISSET(highest_fd, &select_writefds)))
130 highest_fd--;
131 }
132 else if (F->evcache == 0)
133 if (F->fd > highest_fd)
134 highest_fd = F->fd;
135
136 F->evcache = new_events;
137 }
138 }
139
140 /*
141 * comm_select
142 *
143 * Called to do the new-style IO, courtesy of squid (like most of this
144 * new IO code). This routine handles the stuff we've hidden in
145 * comm_setselect and fd_table[] and calls callbacks for IO ready
146 * events.
147 */
148 void
149 comm_select(void)
150 {
151 struct timeval to;
152 int num, fd;
153 fde_t *F;
154 PF *hdl;
155
156 /* Copy over the read/write sets so we don't have to rebuild em */
157 memcpy(&tmpreadfds, &select_readfds, sizeof(fd_set));
158 memcpy(&tmpwritefds, &select_writefds, sizeof(fd_set));
159
160 to.tv_sec = 0;
161 to.tv_usec = SELECT_DELAY * 1000;
162 num = select(highest_fd + 1, &tmpreadfds, &tmpwritefds, NULL, &to);
163
164 set_time();
165
166 if (num < 0)
167 {
168 #ifdef HAVE_USLEEP
169 usleep(50000);
170 #endif
171 return;
172 }
173
174 for (fd = 0; fd <= highest_fd && num > 0; fd++)
175 if (FD_ISSET(fd, &tmpreadfds) || FD_ISSET(fd, &tmpwritefds))
176 {
177 num--;
178
179 F = lookup_fd(fd);
180 if (F == NULL || !F->flags.open)
181 continue;
182
183 if (FD_ISSET(fd, &tmpreadfds))
184 if ((hdl = F->read_handler) != NULL)
185 {
186 F->read_handler = NULL;
187 hdl(F, F->read_data);
188 if (!F->flags.open)
189 continue;
190 }
191
192 if (FD_ISSET(fd, &tmpwritefds))
193 if ((hdl = F->write_handler) != NULL)
194 {
195 F->write_handler = NULL;
196 hdl(F, F->write_data);
197 if (!F->flags.open)
198 continue;
199 }
200
201 comm_setselect(F, 0, NULL, NULL, 0);
202 }
203 }
204 #endif

Properties

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