ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/s_bsd_poll.c
Revision: 1155
Committed: Tue Aug 9 20:27:45 2011 UTC (14 years ago) by michael
Content type: text/x-csrc
Original Path: ircd-hybrid/src/s_bsd_poll.c
File size: 4948 byte(s)
Log Message:
- recreate "trunk"

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

Properties

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