ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/s_bsd_poll.c
Revision: 9101
Committed: Wed Jan 1 09:58:45 2020 UTC (5 years, 7 months ago) by michael
Content type: text/x-csrc
File size: 4750 byte(s)
Log Message:
- Bump copyright years everywhere

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 9101 * Copyright (c) 2000-2020 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 michael 8414 * comm_select_init
52 adx 30 *
53     * This is a needed exported function which will be called to initialise
54     * the network loop code.
55     */
56     void
57 michael 8414 comm_select_init(void)
58 adx 30 {
59 michael 4472 pollfds_size = hard_fdlimit;
60 michael 7032 pollfds = xcalloc(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 michael 7330 void *client_data, uintmax_t timeout)
72 michael 2916 {
73 adx 30 int new_events;
74    
75 michael 8717 assert(F);
76     assert(F->flags.open == true);
77    
78 adx 30 if ((type & COMM_SELECT_READ))
79     {
80     F->read_handler = handler;
81     F->read_data = client_data;
82     }
83    
84     if ((type & COMM_SELECT_WRITE))
85     {
86     F->write_handler = handler;
87     F->write_data = client_data;
88     }
89    
90     new_events = (F->read_handler ? POLLRDNORM : 0) |
91 michael 2650 (F->write_handler ? POLLWRNORM : 0);
92 adx 30
93 michael 8431 if (timeout)
94 michael 2725 {
95 michael 8941 F->timeout = event_base->time.sec_monotonic + timeout;
96 michael 2725 F->timeout_handler = handler;
97     F->timeout_data = client_data;
98     }
99 adx 30
100     if (new_events != F->evcache)
101     {
102     if (new_events == 0)
103     {
104 michael 4472 if (F->comm_index != pollnum - 1)
105     {
106 michael 8339 fde_t *other = &fd_table[pollfds[pollnum - 1].fd];
107 adx 30
108 michael 4472 pollfds[F->comm_index].fd = pollfds[pollnum - 1].fd;
109     pollfds[F->comm_index].events = pollfds[pollnum - 1].events;
110     pollfds[F->comm_index].revents = pollfds[pollnum - 1].revents;
111    
112     assert(other);
113     other->comm_index = F->comm_index;
114     }
115    
116     F->comm_index = -1;
117     --pollnum;
118 adx 30 }
119     else
120     {
121     if (F->evcache == 0)
122     {
123 michael 4472 if (pollnum >= pollfds_size)
124     {
125     pollfds_size *= 2;
126 michael 7032 pollfds = xrealloc(pollfds, sizeof(struct pollfd) * pollfds_size);
127 michael 4472 }
128 adx 30
129 michael 4472 F->comm_index = pollnum++;
130 michael 2650 pollfds[F->comm_index].fd = F->fd;
131 adx 30 }
132 michael 2650
133 adx 30 pollfds[F->comm_index].events = new_events;
134     pollfds[F->comm_index].revents = 0;
135     }
136    
137     F->evcache = new_events;
138     }
139     }
140 michael 2916
141 adx 30 /*
142     * comm_select
143     *
144     * Called to do the new-style IO, courtesy of of squid (like most of this
145     * new IO code). This routine handles the stuff we've hidden in
146     * comm_setselect and fd_table[] and calls callbacks for IO ready
147     * events.
148     */
149     void
150     comm_select(void)
151     {
152 michael 8431 int num;
153 michael 4461 void (*hdl)(fde_t *, void *);
154 adx 30
155 michael 4472 num = poll(pollfds, pollnum, SELECT_DELAY);
156 adx 30
157 michael 8900 event_time_set();
158 adx 30
159     if (num < 0)
160     {
161 michael 6542 const struct timespec req = { .tv_sec = 0, .tv_nsec = 50000000 };
162     nanosleep(&req, NULL); /* Avoid 99% CPU in comm_select */
163 adx 30 return;
164     }
165    
166 michael 8431 for (int ci = 0; ci < pollnum && num > 0; ++ci)
167 adx 30 {
168 michael 4472 int revents = pollfds[ci].revents;
169     if (revents == 0)
170 adx 30 continue;
171    
172 michael 8431 --num;
173    
174 michael 8339 fde_t *F = &fd_table[pollfds[ci].fd];
175    
176 michael 8658 if (F->flags.open == false)
177 adx 30 continue;
178    
179     if (revents & (POLLRDNORM | POLLIN | POLLHUP | POLLERR))
180 michael 2650 {
181 michael 5902 if ((hdl = F->read_handler))
182 adx 30 {
183     F->read_handler = NULL;
184     hdl(F, F->read_data);
185 michael 8339
186 michael 8658 if (F->flags.open == false)
187 michael 2650 continue;
188 adx 30 }
189 michael 2650 }
190 adx 30
191     if (revents & (POLLWRNORM | POLLOUT | POLLHUP | POLLERR))
192 michael 2650 {
193 michael 5902 if ((hdl = F->write_handler))
194 adx 30 {
195     F->write_handler = NULL;
196     hdl(F, F->write_data);
197 michael 8339
198 michael 8658 if (F->flags.open == false)
199 michael 2650 continue;
200 adx 30 }
201 michael 2650 }
202 adx 30
203     comm_setselect(F, 0, NULL, NULL, 0);
204     }
205     }
206 stu 908 #endif

Properties

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