ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/s_bsd_poll.c
Revision: 2916
Committed: Sat Jan 25 21:09:18 2014 UTC (11 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 4718 byte(s)
Log Message:
- Clean up all files in include/ (fixed indentation, removed whitespaces/tabs)
- Fixed copyright years

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 *
4 * Copyright (c) 2000-2014 ircd-hybrid development team
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 * USA
20 */
21
22 /*! \file s_bsd_poll.c
23 * \brief POSIX poll() compatible network routines.
24 * \version $Id$
25 */
26
27 #include "stdinc.h"
28 #if USE_IOPOLL_MECHANISM == __IOPOLL_MECHANISM_POLL
29 #include <sys/poll.h>
30 #include "fdlist.h"
31 #include "list.h"
32 #include "memory.h"
33 #include "hook.h"
34 #include "ircd.h"
35 #include "s_bsd.h"
36 #include "log.h"
37
38 /* I hate linux -- adrian */
39 #ifndef POLLRDNORM
40 #define POLLRDNORM POLLIN
41 #endif
42 #ifndef POLLWRNORM
43 #define POLLWRNORM POLLOUT
44 #endif
45
46 static struct pollfd *pollfds;
47 static int pollmax = -1; /* highest FD number */
48
49
50 /*
51 * init_netio
52 *
53 * This is a needed exported function which will be called to initialise
54 * the network loop code.
55 */
56 void
57 init_netio(void)
58 {
59 int fd;
60
61 pollfds = MyMalloc(sizeof(struct pollfd) * hard_fdlimit);
62
63 for (fd = 0; fd < hard_fdlimit; fd++)
64 pollfds[fd].fd = -1;
65 }
66
67 /*
68 * find a spare slot in the fd list. We can optimise this out later!
69 * -- adrian
70 */
71 static inline int
72 poll_findslot(void)
73 {
74 int i;
75
76 for (i = 0; i < hard_fdlimit; i++)
77 if (pollfds[i].fd == -1)
78 {
79 /* MATCH!!#$*&$ */
80 return i;
81 }
82
83 assert(1 == 0);
84 /* NOTREACHED */
85 return -1;
86 }
87
88 /*
89 * comm_setselect
90 *
91 * This is a needed exported function which will be called to register
92 * and deregister interest in a pending IO state for a given FD.
93 */
94 void
95 comm_setselect(fde_t *F, unsigned int type, PF *handler,
96 void *client_data, time_t timeout)
97 {
98 int new_events;
99
100 if ((type & COMM_SELECT_READ))
101 {
102 F->read_handler = handler;
103 F->read_data = client_data;
104 }
105
106 if ((type & COMM_SELECT_WRITE))
107 {
108 F->write_handler = handler;
109 F->write_data = client_data;
110 }
111
112 new_events = (F->read_handler ? POLLRDNORM : 0) |
113 (F->write_handler ? POLLWRNORM : 0);
114
115 if (timeout != 0)
116 {
117 F->timeout = CurrentTime + (timeout / 1000);
118 F->timeout_handler = handler;
119 F->timeout_data = client_data;
120 }
121
122 if (new_events != F->evcache)
123 {
124 if (new_events == 0)
125 {
126 pollfds[F->comm_index].fd = -1;
127 pollfds[F->comm_index].revents = 0;
128
129 if (pollmax == F->comm_index)
130 while (pollmax >= 0 && pollfds[pollmax].fd == -1)
131 pollmax--;
132 }
133 else
134 {
135 if (F->evcache == 0)
136 {
137 F->comm_index = poll_findslot();
138 if (F->comm_index > pollmax)
139 pollmax = F->comm_index;
140
141 pollfds[F->comm_index].fd = F->fd;
142 }
143
144 pollfds[F->comm_index].events = new_events;
145 pollfds[F->comm_index].revents = 0;
146 }
147
148 F->evcache = new_events;
149 }
150 }
151
152 /*
153 * comm_select
154 *
155 * Called to do the new-style IO, courtesy of of squid (like most of this
156 * new IO code). This routine handles the stuff we've hidden in
157 * comm_setselect and fd_table[] and calls callbacks for IO ready
158 * events.
159 */
160 void
161 comm_select(void)
162 {
163 int num, ci, revents;
164 PF *hdl;
165 fde_t *F;
166
167 /* XXX kill that +1 later ! -- adrian */
168 num = poll(pollfds, pollmax + 1, SELECT_DELAY);
169
170 set_time();
171
172 if (num < 0)
173 {
174 #ifdef HAVE_USLEEP
175 usleep(50000); /* avoid 99% CPU in comm_select */
176 #endif
177 return;
178 }
179
180 for (ci = 0; ci <= pollmax && num > 0; ci++)
181 {
182 if ((revents = pollfds[ci].revents) == 0 || pollfds[ci].fd == -1)
183 continue;
184 num--;
185
186 F = lookup_fd(pollfds[ci].fd);
187 if (F == NULL || !F->flags.open)
188 continue;
189
190 if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
191 {
192 if ((hdl = F->read_handler) != NULL)
193 {
194 F->read_handler = NULL;
195 hdl(F, F->read_data);
196 if (!F->flags.open)
197 continue;
198 }
199 }
200
201 if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR))
202 {
203 if ((hdl = F->write_handler) != NULL)
204 {
205 F->write_handler = NULL;
206 hdl(F, F->write_data);
207 if (!F->flags.open)
208 continue;
209 }
210 }
211
212 comm_setselect(F, 0, NULL, NULL, 0);
213 }
214 }
215 #endif

Properties

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