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
22
23 struct apr_pollset_t {
24 apr_pool_t *pool;
25 apr_uint32_t nelts;
26 apr_uint32_t nalloc;
27 int *pollset;
28 int num_read;
29 int num_write;
30 int num_except;
31 int num_total;
32 apr_pollfd_t *query_set;
33 apr_pollfd_t *result_set;
34 };
35
36
37
apr_pollset_create(apr_pollset_t ** pollset,apr_uint32_t size,apr_pool_t * p,apr_uint32_t flags)38 APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
39 apr_uint32_t size,
40 apr_pool_t *p,
41 apr_uint32_t flags)
42 {
43 *pollset = apr_palloc(p, sizeof(**pollset));
44 (*pollset)->pool = p;
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;
51 return APR_SUCCESS;
52 }
53
54
55
apr_pollset_destroy(apr_pollset_t * pollset)56 APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset)
57 {
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
60 */
61 return APR_SUCCESS;
62 }
63
64
65
apr_pollset_add(apr_pollset_t * pollset,const apr_pollfd_t * descriptor)66 APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset,
67 const apr_pollfd_t *descriptor)
68 {
69 if (pollset->nelts == pollset->nalloc) {
70 return APR_ENOMEM;
71 }
72
73 pollset->query_set[pollset->nelts] = *descriptor;
74
75 if (descriptor->desc_type != APR_POLL_SOCKET) {
76 return APR_EBADF;
77 }
78
79 pollset->nelts++;
80 pollset->num_read = -1;
81 return APR_SUCCESS;
82 }
83
84
85
apr_pollset_remove(apr_pollset_t * pollset,const apr_pollfd_t * descriptor)86 APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
87 const apr_pollfd_t *descriptor)
88 {
89 apr_uint32_t i;
90
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 */
94 apr_uint32_t dst = i;
95 apr_uint32_t old_nelts = pollset->nelts;
96 pollset->nelts--;
97
98 for (i++; i < old_nelts; i++) {
99 if (descriptor->desc.s == pollset->query_set[i].desc.s) {
100 pollset->nelts--;
101 }
102 else {
103 pollset->pollset[dst] = pollset->pollset[i];
104 pollset->query_set[dst] = pollset->query_set[i];
105 dst++;
106 }
107 }
108
109 pollset->num_read = -1;
110 return APR_SUCCESS;
111 }
112 }
113
114 return APR_NOTFOUND;
115 }
116
117
118
make_pollset(apr_pollset_t * pollset)119 static void make_pollset(apr_pollset_t *pollset)
120 {
121 int i;
122 int pos = 0;
123
124 pollset->num_read = 0;
125 pollset->num_write = 0;
126 pollset->num_except = 0;
127
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;
131 pollset->num_read++;
132 }
133 }
134
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++;
139 }
140 }
141
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++;
146 }
147 }
148
149 pollset->num_total = pollset->num_read + pollset->num_write + pollset->num_except;
150 }
151
152
153
apr_pollset_poll(apr_pollset_t * pollset,apr_interval_time_t timeout,apr_int32_t * num,const apr_pollfd_t ** descriptors)154 APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset,
155 apr_interval_time_t timeout,
156 apr_int32_t *num,
157 const apr_pollfd_t **descriptors)
158 {
159 int rv;
160 apr_uint32_t i;
161 int *pollresult;
162 int read_pos, write_pos, except_pos;
163
164 if (pollset->num_read < 0) {
165 make_pollset(pollset);
166 }
167
168 pollresult = alloca(sizeof(int) * pollset->num_total);
169 memcpy(pollresult, pollset->pollset, sizeof(int) * pollset->num_total);
170 (*num) = 0;
171
172 if (timeout > 0) {
173 timeout /= 1000;
174 }
175
176 rv = select(pollresult, pollset->num_read, pollset->num_write, pollset->num_except, timeout);
177
178 if (rv < 0) {
179 return APR_FROM_OS_ERROR(sock_errno());
180 }
181
182 if (rv == 0) {
183 return APR_TIMEUP;
184 }
185
186 read_pos = 0;
187 write_pos = pollset->num_read;
188 except_pos = pollset->num_read + pollset->num_write;
189
190 for (i = 0; i < pollset->nelts; i++) {
191 int rtnevents = 0;
192
193 if (pollset->query_set[i].reqevents & APR_POLLIN) {
194 if (pollresult[read_pos++] != -1) {
195 rtnevents |= APR_POLLIN;
196 }
197 }
198
199 if (pollset->query_set[i].reqevents & APR_POLLOUT) {
200 if (pollresult[write_pos++] != -1) {
201 rtnevents |= APR_POLLOUT;
202 }
203 }
204
205 if (pollset->query_set[i].reqevents & APR_POLLPRI) {
206 if (pollresult[except_pos++] != -1) {
207 rtnevents |= APR_POLLPRI;
208 }
209 }
210
211 if (rtnevents) {
212 pollset->result_set[*num] = pollset->query_set[i];
213 pollset->result_set[*num].rtnevents = rtnevents;
214 (*num)++;
215 }
216 }
217
218 if (descriptors) {
219 *descriptors = pollset->result_set;
220 }
221
222 return APR_SUCCESS;
223 }
224