ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-8/src/s_bsd_select.c
Revision: 33
Committed: Sun Oct 2 20:50:00 2005 UTC (19 years, 10 months ago) by knight
Content type: text/x-csrc
Original Path: ircd-hybrid/src/s_bsd_select.c
File size: 4799 byte(s)
Log Message:
- svn:keywords

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

Properties

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