1
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as
4
* Licensed under the Apache License, Version 2.0 (the "License");
5
* you may not use this file except in compliance with the License.
6
* You may obtain a copy of the License at
8
* http://www.apache.org/licenses/LICENSE-2.0
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.
19
#include "apr_arch_networkio.h"
23
struct apr_pollset_t {
32
apr_pollfd_t *query_set;
33
apr_pollfd_t *result_set;
38
APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
43
*pollset = apr_palloc(p, sizeof(**pollset));
45
(*pollset)->nelts = 0;
46
(*pollset)->nalloc = size;
47
(*pollset)->pollset = apr_palloc(p, size * sizeof(int) * 3);
48
(*pollset)->query_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
49
(*pollset)->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
50
(*pollset)->num_read = -1;
56
APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset)
58
/* A no-op function for now. If we later implement /dev/poll
59
* support, we'll need to close the /dev/poll fd here
66
APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset,
67
const apr_pollfd_t *descriptor)
69
if (pollset->nelts == pollset->nalloc) {
73
pollset->query_set[pollset->nelts] = *descriptor;
75
if (descriptor->desc_type != APR_POLL_SOCKET) {
80
pollset->num_read = -1;
86
APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
87
const apr_pollfd_t *descriptor)
91
for (i = 0; i < pollset->nelts; i++) {
92
if (descriptor->desc.s == pollset->query_set[i].desc.s) {
93
/* Found an instance of the fd: remove this and any other copies */
95
apr_uint32_t old_nelts = pollset->nelts;
98
for (i++; i < old_nelts; i++) {
99
if (descriptor->desc.s == pollset->query_set[i].desc.s) {
103
pollset->pollset[dst] = pollset->pollset[i];
104
pollset->query_set[dst] = pollset->query_set[i];
109
pollset->num_read = -1;
119
static void make_pollset(apr_pollset_t *pollset)
124
pollset->num_read = 0;
125
pollset->num_write = 0;
126
pollset->num_except = 0;
128
for (i = 0; i < pollset->nelts; i++) {
129
if (pollset->query_set[i].reqevents & APR_POLLIN) {
130
pollset->pollset[pos++] = pollset->query_set[i].desc.s->socketdes;
135
for (i = 0; i < pollset->nelts; i++) {
136
if (pollset->query_set[i].reqevents & APR_POLLOUT) {
137
pollset->pollset[pos++] = pollset->query_set[i].desc.s->socketdes;
138
pollset->num_write++;
142
for (i = 0; i < pollset->nelts; i++) {
143
if (pollset->query_set[i].reqevents & APR_POLLPRI) {
144
pollset->pollset[pos++] = pollset->query_set[i].desc.s->socketdes;
145
pollset->num_except++;
149
pollset->num_total = pollset->num_read + pollset->num_write + pollset->num_except;
154
APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset,
155
apr_interval_time_t timeout,
157
const apr_pollfd_t **descriptors)
162
int read_pos, write_pos, except_pos;
164
if (pollset->num_read < 0) {
165
make_pollset(pollset);
168
pollresult = alloca(sizeof(int) * pollset->num_total);
169
memcpy(pollresult, pollset->pollset, sizeof(int) * pollset->num_total);
176
rv = select(pollresult, pollset->num_read, pollset->num_write, pollset->num_except, timeout);
179
return APR_FROM_OS_ERROR(sock_errno());
187
write_pos = pollset->num_read;
188
except_pos = pollset->num_read + pollset->num_write;
190
for (i = 0; i < pollset->nelts; i++) {
193
if (pollset->query_set[i].reqevents & APR_POLLIN) {
194
if (pollresult[read_pos++] != -1) {
195
rtnevents |= APR_POLLIN;
199
if (pollset->query_set[i].reqevents & APR_POLLOUT) {
200
if (pollresult[write_pos++] != -1) {
201
rtnevents |= APR_POLLOUT;
205
if (pollset->query_set[i].reqevents & APR_POLLPRI) {
206
if (pollresult[except_pos++] != -1) {
207
rtnevents |= APR_POLLPRI;
212
pollset->result_set[*num] = pollset->query_set[i];
213
pollset->result_set[*num].rtnevents = rtnevents;
219
*descriptors = pollset->result_set;