Apache HTTPD
pollset.c
Go to the documentation of this file.
1/* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "apr.h"
18#include "apr_poll.h"
19#include "apr_arch_networkio.h"
20
21#ifndef MSG_DONTWAIT
22#define MSG_DONTWAIT 0x100
23#endif
24
25struct apr_pollset_t {
29 int *pollset;
39};
40
41
42
47{
49
51 size++;
52 }
53
54 *pollset = apr_palloc(p, sizeof(**pollset));
55 (*pollset)->pool = p;
56 (*pollset)->nelts = 0;
57 (*pollset)->nalloc = size;
58 (*pollset)->pollset = apr_palloc(p, size * sizeof(int) * 3);
59 (*pollset)->query_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
60 (*pollset)->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
61 (*pollset)->num_read = -1;
62 (*pollset)->wake_listen = NULL;
63 (*pollset)->wake_sender = NULL;
64
66 rc = apr_socket_create(&(*pollset)->wake_listen, APR_UNIX, SOCK_DGRAM, 0, p);
67
68 if (rc == APR_SUCCESS) {
70 apr_socket_timeout_set((*pollset)->wake_listen, 0);
72 rc = apr_socket_bind((*pollset)->wake_listen, listen_address);
73
74 if (rc == APR_SUCCESS) {
77 wake_poll_fd.desc_type = APR_POLL_SOCKET;
78 wake_poll_fd.reqevents = APR_POLLIN;
79 wake_poll_fd.desc.s = (*pollset)->wake_listen;
80 wake_poll_fd.client_data = NULL;
82 apr_socket_addr_get(&(*pollset)->wake_address, APR_LOCAL, (*pollset)->wake_listen);
83
84 rc = apr_socket_create(&(*pollset)->wake_sender, APR_UNIX, SOCK_DGRAM, 0, p);
85 }
86 }
87 }
88
89 return rc;
90}
91
97{
98 /* Only one method is supported */
101 return APR_ENOTIMPL;
102 }
103 }
104
106}
107
109{
110 /* A no-op function for now. If we later implement /dev/poll
111 * support, we'll need to close the /dev/poll fd here
112 */
113 return APR_SUCCESS;
114}
115
116
117
120{
121 if (pollset->nelts == pollset->nalloc) {
122 return APR_ENOMEM;
123 }
124
126
128 return APR_EBADF;
129 }
130
131 pollset->nelts++;
132 pollset->num_read = -1;
133 return APR_SUCCESS;
134}
135
136
137
140{
142
143 for (i = 0; i < pollset->nelts; i++) {
144 if (descriptor->desc.s == pollset->query_set[i].desc.s) {
145 /* Found an instance of the fd: remove this and any other copies */
148 pollset->nelts--;
149
150 for (i++; i < old_nelts; i++) {
151 if (descriptor->desc.s == pollset->query_set[i].desc.s) {
152 pollset->nelts--;
153 }
154 else {
157 dst++;
158 }
159 }
160
161 pollset->num_read = -1;
162 return APR_SUCCESS;
163 }
164 }
165
166 return APR_NOTFOUND;
167}
168
169
170
172{
173 int i;
174 int pos = 0;
175
176 pollset->num_read = 0;
177 pollset->num_write = 0;
178 pollset->num_except = 0;
179
180 for (i = 0; i < pollset->nelts; i++) {
183 pollset->num_read++;
184 }
185 }
186
187 for (i = 0; i < pollset->nelts; i++) {
191 }
192 }
193
194 for (i = 0; i < pollset->nelts; i++) {
198 }
199 }
200
202}
203
204
205
210{
211 int rv;
213 int *pollresult;
216
217 if (pollset->num_read < 0) {
219 }
220
221 pollresult = alloca(sizeof(int) * pollset->num_total);
223 (*num) = 0;
224
225 if (timeout > 0) {
226 timeout = (timeout + 999) / 1000;
227 }
228
230
231 if (rv < 0) {
233 }
234
235 if (rv == 0) {
236 return APR_TIMEUP;
237 }
238
239 read_pos = 0;
242
243 for (i = 0; i < pollset->nelts; i++) {
244 int rtnevents = 0;
245
247 if (pollresult[read_pos++] != -1) {
248 rtnevents |= APR_POLLIN;
249 }
250 }
251
253 if (pollresult[write_pos++] != -1) {
254 rtnevents |= APR_POLLOUT;
255 }
256 }
257
259 if (pollresult[except_pos++] != -1) {
260 rtnevents |= APR_POLLPRI;
261 }
262 }
263
264 if (rtnevents) {
265 if (i == 0 && pollset->wake_listen != NULL) {
267 char buffer[16];
269 for (;;) {
270 buflen = sizeof(buffer);
273 if (rv != APR_SUCCESS) {
274 break;
275 }
276 /* Woken up, drain the pipe still. */
277 rc = APR_EINTR;
278 }
279 }
280 else {
282 pollset->result_set[*num].rtnevents = rtnevents;
283 /* Event(s) besides wakeup pipe. */
284 rc = APR_SUCCESS;
285 (*num)++;
286 }
287 }
288 }
289
290 if (descriptors) {
292 }
293
294 return rc;
295}
296
297
298
300{
301 if (pollset->wake_sender) {
302 apr_size_t len = 1;
304 }
305
306 return APR_EINIT;
307}
308
309
310
312{
313 return "select";
314}
315
316
317
319{
320 return "select";
321}
const char apr_size_t len
Definition ap_regex.h:187
#define select
#define sock_errno
APR Poll interface.
#define APR_EBADF
Definition apr_errno.h:704
#define APR_ENOMEM
Definition apr_errno.h:683
#define APR_ENOTIMPL
Definition apr_errno.h:476
#define APR_TIMEUP
Definition apr_errno.h:450
#define APR_NOTFOUND
Definition apr_errno.h:463
#define APR_EINIT
Definition apr_errno.h:474
#define APR_EINTR
Definition apr_errno.h:737
const char apr_ssize_t int flags
Definition apr_encode.h:168
apr_redis_t * rc
Definition apr_redis.h:173
const void apr_status_t(*) apr_status_t(* APR_DECLARE)(void) apr_pool_pre_cleanup_register(apr_pool_t *p
Definition apr_pools.h:646
apr_size_t size
#define APR_FROM_OS_ERROR(e)
Definition apr_errno.h:1214
#define APR_SUCCESS
Definition apr_errno.h:225
int apr_status_t
Definition apr_errno.h:44
char * buffer
apr_size_t buflen
#define APR_UNIX
@ APR_LOCAL
apr_uint32_t apr_pool_t apr_uint32_t apr_pollset_method_e method
Definition apr_poll.h:195
apr_interval_time_t apr_int32_t const apr_pollfd_t ** descriptors
Definition apr_poll.h:274
apr_interval_time_t apr_int32_t * num
Definition apr_poll.h:273
const apr_pollfd_t * descriptor
Definition apr_poll.h:230
apr_pollset_method_e
Definition apr_poll.h:80
@ APR_POLL_SOCKET
Definition apr_poll.h:93
@ APR_POLLSET_POLL
Definition apr_poll.h:86
@ APR_POLLSET_DEFAULT
Definition apr_poll.h:81
apr_int64_t apr_interval_time_t
Definition apr_time.h:55
#define APR_POLLSET_WAKEABLE
Definition apr_poll.h:68
#define APR_POLLSET_NODEFAULT
Definition apr_poll.h:71
#define APR_POLLPRI
Definition apr_poll.h:50
#define APR_POLLOUT
Definition apr_poll.h:51
#define APR_POLLIN
Definition apr_poll.h:49
apr_pool_t * p
Definition md_event.c:32
return NULL
Definition mod_so.c:359
int i
Definition mod_so.c:347
static void make_pollset(apr_pollset_t *pollset)
Definition pollset.c:171
#define MSG_DONTWAIT
Definition pollset.c:22
apr_int16_t reqevents
Definition apr_poll.h:111
apr_datatype_e desc_type
Definition apr_poll.h:110
apr_descriptor desc
Definition apr_poll.h:113
apr_pool_t * p
Definition apr_poll.h:109
apr_int16_t rtnevents
Definition apr_poll.h:112
apr_socket_t * wake_listen
Definition pollset.c:36
apr_sockaddr_t * wake_address
Definition pollset.c:38
int * pollset
Definition pollset.c:29
int num_except
Definition pollset.c:32
int num_write
Definition pollset.c:31
apr_pollfd_t * query_set
Definition pollset.c:34
int num_total
Definition pollset.c:33
apr_pollfd_t * result_set
Definition pollset.c:35
apr_socket_t * wake_sender
Definition pollset.c:37
static apr_pollset_t * pollset
Definition testpoll.c:41
apr_socket_t * s
Definition apr_poll.h:101
apr_status_t apr_socket_sendto(apr_socket_t *sock, apr_sockaddr_t *where, apr_int32_t flags, const char *buf, apr_size_t *len)
Definition sendrecv.c:112
apr_status_t apr_socket_recvfrom(apr_sockaddr_t *from, apr_socket_t *sock, apr_int32_t flags, char *buf, apr_size_t *len)
Definition sendrecv.c:146
apr_status_t apr_socket_bind(apr_socket_t *sock, apr_sockaddr_t *sa)
Definition sockets.c:216
apr_status_t apr_socket_create(apr_socket_t **new, int ofamily, int type, int protocol, apr_pool_t *cont)
Definition sockets.c:116
apr_status_t apr_socket_timeout_set(apr_socket_t *sock, apr_interval_time_t t)
Definition sockopt.c:75
IN ULONG IN INT timeout