ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/s_bsd_poll.c
Revision: 1736
Committed: Sun Jan 13 09:31:46 2013 UTC (12 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 4540 byte(s)
Log Message:
- Forward-port -r1732 [Dropped support for linux rt signals]

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 michael 1309 #include "log.h"
35 adx 30
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    
47    
48     /*
49     * init_netio
50     *
51     * This is a needed exported function which will be called to initialise
52     * the network loop code.
53     */
54     void
55     init_netio(void)
56     {
57     int fd;
58    
59     pollfds = MyMalloc(sizeof(struct pollfd) * hard_fdlimit);
60    
61     for (fd = 0; fd < hard_fdlimit; fd++)
62     pollfds[fd].fd = -1;
63     }
64    
65     /*
66     * find a spare slot in the fd list. We can optimise this out later!
67     * -- adrian
68     */
69     static inline int
70     poll_findslot(void)
71     {
72     int i;
73    
74     for (i = 0; i < hard_fdlimit; i++)
75     if (pollfds[i].fd == -1)
76     {
77     /* MATCH!!#$*&$ */
78     return i;
79     }
80    
81     assert(1 == 0);
82     /* NOTREACHED */
83     return -1;
84     }
85    
86     /*
87     * comm_setselect
88     *
89     * This is a needed exported function which will be called to register
90     * and deregister interest in a pending IO state for a given FD.
91     */
92     void
93     comm_setselect(fde_t *F, unsigned int type, PF *handler,
94     void *client_data, time_t timeout)
95     {
96     int new_events;
97    
98     if ((type & COMM_SELECT_READ))
99     {
100     F->read_handler = handler;
101     F->read_data = client_data;
102     }
103    
104     if ((type & COMM_SELECT_WRITE))
105     {
106     F->write_handler = handler;
107     F->write_data = client_data;
108     }
109    
110     new_events = (F->read_handler ? POLLRDNORM : 0) |
111     (F->write_handler ? POLLWRNORM : 0);
112    
113     if (timeout != 0)
114     F->timeout = CurrentTime + (timeout / 1000);
115    
116     if (new_events != F->evcache)
117     {
118     if (new_events == 0)
119     {
120     pollfds[F->comm_index].fd = -1;
121     pollfds[F->comm_index].revents = 0;
122    
123     if (pollmax == F->comm_index)
124     while (pollmax >= 0 && pollfds[pollmax].fd == -1)
125     pollmax--;
126     }
127     else
128     {
129     if (F->evcache == 0)
130     {
131     F->comm_index = poll_findslot();
132     if (F->comm_index > pollmax)
133     pollmax = F->comm_index;
134    
135     pollfds[F->comm_index].fd = F->fd;
136     }
137     pollfds[F->comm_index].events = new_events;
138     pollfds[F->comm_index].revents = 0;
139     }
140    
141     F->evcache = new_events;
142     }
143     }
144    
145     /*
146     * comm_select
147     *
148     * Called to do the new-style IO, courtesy of of squid (like most of this
149     * new IO code). This routine handles the stuff we've hidden in
150     * comm_setselect and fd_table[] and calls callbacks for IO ready
151     * events.
152     */
153     void
154     comm_select(void)
155     {
156     int num, ci, revents;
157     PF *hdl;
158     fde_t *F;
159    
160     /* XXX kill that +1 later ! -- adrian */
161     num = poll(pollfds, pollmax + 1, SELECT_DELAY);
162    
163     set_time();
164    
165     if (num < 0)
166     {
167     #ifdef HAVE_USLEEP
168     usleep(50000); /* avoid 99% CPU in comm_select */
169     #endif
170     return;
171     }
172    
173     for (ci = 0; ci <= pollmax && num > 0; ci++)
174     {
175     if ((revents = pollfds[ci].revents) == 0 || pollfds[ci].fd == -1)
176     continue;
177     num--;
178    
179     F = lookup_fd(pollfds[ci].fd);
180     if (F == NULL || !F->flags.open)
181     continue;
182    
183     if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
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 (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR))
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 stu 908 #endif

Properties

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