bottleneck testcase based on rubbos
[bottlenecks.git] / rubbos / app / httpd-2.0.64 / srclib / apr / poll / os2 / pollset.c
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
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
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
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
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
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
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     *descriptors = pollset->result_set;
219     return APR_SUCCESS;
220 }