ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid-7.3/src/s_bsd_poll.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_poll.c
File size: 4930 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_poll.c: POSIX poll() 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_POLL
28 adx 30 #include <sys/poll.h>
29     #include "fdlist.h"
30     #include "hook.h"
31     #include "ircd.h"
32     #include "s_bsd.h"
33     #include "s_log.h"
34    
35     /* I hate linux -- adrian */
36     #ifndef POLLRDNORM
37     #define POLLRDNORM POLLIN
38     #endif
39     #ifndef POLLWRNORM
40     #define POLLWRNORM POLLOUT
41     #endif
42    
43     static struct pollfd *pollfds;
44     static int pollmax = -1; /* highest FD number */
45     static dlink_node *hookptr;
46    
47     /*
48     * changing_fdlimit
49     *
50     * Resize pollfds array if necessary.
51     */
52     static void *
53     changing_fdlimit(va_list args)
54     {
55     int old_fdlimit = hard_fdlimit;
56    
57     pass_callback(hookptr, va_arg(args, int));
58    
59     if (hard_fdlimit != old_fdlimit)
60     pollfds = MyRealloc(pollfds, sizeof(struct pollfd) * hard_fdlimit);
61    
62     return NULL;
63     }
64    
65     /*
66     * init_netio
67     *
68     * This is a needed exported function which will be called to initialise
69     * the network loop code.
70     */
71     void
72     init_netio(void)
73     {
74     int fd;
75    
76     pollfds = MyMalloc(sizeof(struct pollfd) * hard_fdlimit);
77    
78     for (fd = 0; fd < hard_fdlimit; fd++)
79     pollfds[fd].fd = -1;
80    
81     hookptr = install_hook(fdlimit_cb, changing_fdlimit);
82     }
83    
84     /*
85     * find a spare slot in the fd list. We can optimise this out later!
86     * -- adrian
87     */
88     static inline int
89     poll_findslot(void)
90     {
91     int i;
92    
93     for (i = 0; i < hard_fdlimit; i++)
94     if (pollfds[i].fd == -1)
95     {
96     /* MATCH!!#$*&$ */
97     return i;
98     }
99    
100     assert(1 == 0);
101     /* NOTREACHED */
102     return -1;
103     }
104    
105     /*
106     * comm_setselect
107     *
108     * This is a needed exported function which will be called to register
109     * and deregister interest in a pending IO state for a given FD.
110     */
111     void
112     comm_setselect(fde_t *F, unsigned int type, PF *handler,
113     void *client_data, time_t timeout)
114     {
115     int new_events;
116    
117     if ((type & COMM_SELECT_READ))
118     {
119     F->read_handler = handler;
120     F->read_data = client_data;
121     }
122    
123     if ((type & COMM_SELECT_WRITE))
124     {
125     F->write_handler = handler;
126     F->write_data = client_data;
127     }
128    
129     new_events = (F->read_handler ? POLLRDNORM : 0) |
130     (F->write_handler ? POLLWRNORM : 0);
131    
132     if (timeout != 0)
133     F->timeout = CurrentTime + (timeout / 1000);
134    
135     if (new_events != F->evcache)
136     {
137     if (new_events == 0)
138     {
139     pollfds[F->comm_index].fd = -1;
140     pollfds[F->comm_index].revents = 0;
141    
142     if (pollmax == F->comm_index)
143     while (pollmax >= 0 && pollfds[pollmax].fd == -1)
144     pollmax--;
145     }
146     else
147     {
148     if (F->evcache == 0)
149     {
150     F->comm_index = poll_findslot();
151     if (F->comm_index > pollmax)
152     pollmax = F->comm_index;
153    
154     pollfds[F->comm_index].fd = F->fd;
155     }
156     pollfds[F->comm_index].events = new_events;
157     pollfds[F->comm_index].revents = 0;
158     }
159    
160     F->evcache = new_events;
161     }
162     }
163    
164     /*
165     * comm_select
166     *
167     * Called to do the new-style IO, courtesy of of squid (like most of this
168     * new IO code). This routine handles the stuff we've hidden in
169     * comm_setselect and fd_table[] and calls callbacks for IO ready
170     * events.
171     */
172     void
173     comm_select(void)
174     {
175     int num, ci, revents;
176     PF *hdl;
177     fde_t *F;
178    
179     /* XXX kill that +1 later ! -- adrian */
180     num = poll(pollfds, pollmax + 1, SELECT_DELAY);
181    
182     set_time();
183    
184     if (num < 0)
185     {
186     #ifdef HAVE_USLEEP
187     usleep(50000); /* avoid 99% CPU in comm_select */
188     #endif
189     return;
190     }
191    
192     for (ci = 0; ci <= pollmax && num > 0; ci++)
193     {
194     if ((revents = pollfds[ci].revents) == 0 || pollfds[ci].fd == -1)
195     continue;
196     num--;
197    
198     F = lookup_fd(pollfds[ci].fd);
199     if (F == NULL || !F->flags.open)
200     continue;
201    
202     if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
203     if ((hdl = F->read_handler) != NULL)
204     {
205     F->read_handler = NULL;
206     hdl(F, F->read_data);
207     if (!F->flags.open)
208     continue;
209     }
210    
211     if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR))
212     if ((hdl = F->write_handler) != NULL)
213     {
214     F->write_handler = NULL;
215     hdl(F, F->write_data);
216     if (!F->flags.open)
217     continue;
218     }
219    
220     comm_setselect(F, 0, NULL, NULL, 0);
221     }
222     }
223 stu 908 #endif

Properties

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