ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/s_bsd_poll.c
Revision: 6542
Committed: Wed Sep 16 11:01:51 2015 UTC (9 years, 11 months ago) by michael
Content type: text/x-csrc
File size: 4672 byte(s)
Log Message:
- Replace obsolete usleep() with nanosleep()

File Contents

# User Rev Content
1 adx 30 /*
2 michael 2916 * ircd-hybrid: an advanced, lightweight Internet Relay Chat Daemon (ircd)
3 adx 30 *
4 michael 5347 * Copyright (c) 2000-2015 ircd-hybrid development team
5 adx 30 *
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 michael 4565 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
19 adx 30 * USA
20     */
21    
22 michael 2916 /*! \file s_bsd_poll.c
23     * \brief POSIX poll() compatible network routines.
24     * \version $Id$
25     */
26    
27 adx 30 #include "stdinc.h"
28 stu 908 #if USE_IOPOLL_MECHANISM == __IOPOLL_MECHANISM_POLL
29 adx 30 #include <sys/poll.h>
30     #include "fdlist.h"
31 michael 1021 #include "list.h"
32 michael 2627 #include "memory.h"
33 adx 30 #include "ircd.h"
34     #include "s_bsd.h"
35 michael 1309 #include "log.h"
36 adx 30
37     /* I hate linux -- adrian */
38     #ifndef POLLRDNORM
39     #define POLLRDNORM POLLIN
40     #endif
41     #ifndef POLLWRNORM
42     #define POLLWRNORM POLLOUT
43     #endif
44    
45 michael 4472 static int pollfds_size;
46 adx 30 static struct pollfd *pollfds;
47 michael 4472 static int pollnum;
48 adx 30
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 michael 4472 pollfds_size = hard_fdlimit;
60     pollfds = MyCalloc(sizeof(struct pollfd) * pollfds_size);
61 adx 30 }
62    
63     /*
64     * comm_setselect
65     *
66     * This is a needed exported function which will be called to register
67     * and deregister interest in a pending IO state for a given FD.
68     */
69     void
70 michael 4461 comm_setselect(fde_t *F, unsigned int type, void (*handler)(fde_t *, void *),
71 adx 30 void *client_data, time_t timeout)
72 michael 2916 {
73 adx 30 int new_events;
74    
75     if ((type & COMM_SELECT_READ))
76     {
77     F->read_handler = handler;
78     F->read_data = client_data;
79     }
80    
81     if ((type & COMM_SELECT_WRITE))
82     {
83     F->write_handler = handler;
84     F->write_data = client_data;
85     }
86    
87     new_events = (F->read_handler ? POLLRDNORM : 0) |
88 michael 2650 (F->write_handler ? POLLWRNORM : 0);
89 adx 30
90     if (timeout != 0)
91 michael 2725 {
92 adx 30 F->timeout = CurrentTime + (timeout / 1000);
93 michael 2725 F->timeout_handler = handler;
94     F->timeout_data = client_data;
95     }
96 adx 30
97     if (new_events != F->evcache)
98     {
99     if (new_events == 0)
100     {
101 michael 4472 if (F->comm_index != pollnum - 1)
102     {
103     fde_t *other = lookup_fd(pollfds[pollnum - 1].fd);
104 adx 30
105 michael 4472 pollfds[F->comm_index].fd = pollfds[pollnum - 1].fd;
106     pollfds[F->comm_index].events = pollfds[pollnum - 1].events;
107     pollfds[F->comm_index].revents = pollfds[pollnum - 1].revents;
108    
109     assert(other);
110     other->comm_index = F->comm_index;
111     }
112    
113     F->comm_index = -1;
114     --pollnum;
115 adx 30 }
116     else
117     {
118     if (F->evcache == 0)
119     {
120 michael 4472 if (pollnum >= pollfds_size)
121     {
122     pollfds_size *= 2;
123     pollfds = MyRealloc(pollfds, sizeof(struct pollfd) * pollfds_size);
124     }
125 adx 30
126 michael 4472 F->comm_index = pollnum++;
127 michael 2650 pollfds[F->comm_index].fd = F->fd;
128 adx 30 }
129 michael 2650
130 adx 30 pollfds[F->comm_index].events = new_events;
131     pollfds[F->comm_index].revents = 0;
132     }
133    
134     F->evcache = new_events;
135     }
136     }
137 michael 2916
138 adx 30 /*
139     * comm_select
140     *
141     * Called to do the new-style IO, courtesy of 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 michael 4472 int num, ci;
150 michael 4461 void (*hdl)(fde_t *, void *);
151 adx 30 fde_t *F;
152    
153 michael 4472 num = poll(pollfds, pollnum, SELECT_DELAY);
154 adx 30
155     set_time();
156    
157     if (num < 0)
158     {
159 michael 6542 const struct timespec req = { .tv_sec = 0, .tv_nsec = 50000000 };
160     nanosleep(&req, NULL); /* Avoid 99% CPU in comm_select */
161 adx 30 return;
162     }
163    
164 michael 4472 for (ci = 0; ci < pollnum && num > 0; ci++)
165 adx 30 {
166 michael 4472 int revents = pollfds[ci].revents;
167    
168     if (revents == 0)
169 adx 30 continue;
170     num--;
171    
172     F = lookup_fd(pollfds[ci].fd);
173 michael 4472 assert(F);
174     if (!F->flags.open)
175 adx 30 continue;
176    
177     if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
178 michael 2650 {
179 michael 5902 if ((hdl = F->read_handler))
180 adx 30 {
181     F->read_handler = NULL;
182     hdl(F, F->read_data);
183 michael 2650 if (!F->flags.open)
184     continue;
185 adx 30 }
186 michael 2650 }
187 adx 30
188     if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR))
189 michael 2650 {
190 michael 5902 if ((hdl = F->write_handler))
191 adx 30 {
192     F->write_handler = NULL;
193     hdl(F, F->write_data);
194 michael 2650 if (!F->flags.open)
195     continue;
196 adx 30 }
197 michael 2650 }
198 adx 30
199     comm_setselect(F, 0, NULL, NULL, 0);
200     }
201     }
202 stu 908 #endif

Properties

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