ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/s_bsd_select.c
Revision: 908
Committed: Sun Nov 4 23:21:51 2007 UTC (17 years, 9 months ago) by stu
Content type: text/x-csrc
Original Path: ircd-hybrid-7.2/src/s_bsd_select.c
File size: 4860 byte(s)
Log Message:
Completely redo the build system.  Now uses libtool and automake.  Suggest you clean out your tree and then do ./autogen.sh.

File Contents

# User Rev Content
1 adx 30 /*
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 knight 31 * $Id$
24 adx 30 */
25    
26     #include "stdinc.h"
27 stu 908 #if USE_IOPOLL_MECHANISM == __IOPOLL_MECHANISM_SELECT
28 adx 30 #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 stu 908 #endif

Properties

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