]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/apr/poll/unix/pollcb.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / apr / poll / unix / pollcb.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 #ifdef WIN32
18 /* POSIX defines 1024 for the FD_SETSIZE */
19 #define FD_SETSIZE 1024
20 #endif
21
22 #include "apr.h"
23 #include "apr_poll.h"
24 #include "apr_time.h"
25 #include "apr_portable.h"
26 #include "apr_arch_file_io.h"
27 #include "apr_arch_networkio.h"
28 #include "apr_arch_poll_private.h"
29
30 static apr_pollset_method_e pollset_default_method = POLLSET_DEFAULT_METHOD;
31 #if defined(HAVE_KQUEUE)
32 extern apr_pollcb_provider_t *apr_pollcb_provider_kqueue;
33 #endif
34 #if defined(HAVE_PORT_CREATE)
35 extern apr_pollcb_provider_t *apr_pollcb_provider_port;
36 #endif
37 #if defined(HAVE_EPOLL)
38 extern apr_pollcb_provider_t *apr_pollcb_provider_epoll;
39 #endif
40 #if defined(HAVE_POLL)
41 extern apr_pollcb_provider_t *apr_pollcb_provider_poll;
42 #endif
43
44 static apr_pollcb_provider_t *pollcb_provider(apr_pollset_method_e method)
45 {
46     apr_pollcb_provider_t *provider = NULL;
47     switch (method) {
48         case APR_POLLSET_KQUEUE:
49 #if defined(HAVE_KQUEUE)
50             provider = apr_pollcb_provider_kqueue;
51 #endif
52         break;
53         case APR_POLLSET_PORT:
54 #if defined(HAVE_PORT_CREATE)
55             provider = apr_pollcb_provider_port;
56 #endif
57         break;
58         case APR_POLLSET_EPOLL:
59 #if defined(HAVE_EPOLL)
60             provider = apr_pollcb_provider_epoll;
61 #endif
62         break;
63         case APR_POLLSET_POLL:
64 #if defined(HAVE_POLL)
65             provider = apr_pollcb_provider_poll;
66 #endif
67         break;
68         case APR_POLLSET_SELECT:
69         case APR_POLLSET_DEFAULT:
70         break;
71     }
72     return provider;
73 }
74
75 APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **ret_pollcb,
76                                                apr_uint32_t size,
77                                                apr_pool_t *p,
78                                                apr_uint32_t flags,
79                                                apr_pollset_method_e method)
80 {
81     apr_status_t rv;
82     apr_pollcb_t *pollcb;
83     apr_pollcb_provider_t *provider = NULL;
84
85     *ret_pollcb = NULL;
86
87  #ifdef WIN32
88     /* This will work only if ws2_32.dll has WSAPoll funtion.
89      * We could check the presence of the function here,
90      * but someone might implement other pollcb method in
91      * the future.
92      */
93     if (method == APR_POLLSET_DEFAULT) {
94         method = APR_POLLSET_POLL;
95     }
96  #endif
97
98     if (method == APR_POLLSET_DEFAULT)
99         method = pollset_default_method;
100     while (provider == NULL) {
101         provider = pollcb_provider(method);
102         if (!provider) {
103             if ((flags & APR_POLLSET_NODEFAULT) == APR_POLLSET_NODEFAULT)
104                 return APR_ENOTIMPL;
105             if (method == pollset_default_method)
106                 return APR_ENOTIMPL;
107             method = pollset_default_method;
108         }
109     }
110
111     pollcb = apr_palloc(p, sizeof(*pollcb));
112     pollcb->nelts = 0;
113     pollcb->nalloc = size;
114     pollcb->pool = p;
115     pollcb->provider = provider;
116
117     rv = (*provider->create)(pollcb, size, p, flags);
118     if (rv == APR_ENOTIMPL) {
119         if (method == pollset_default_method) {
120             return rv;
121         }
122
123         if ((flags & APR_POLLSET_NODEFAULT) == APR_POLLSET_NODEFAULT) {
124             return rv;
125         }
126
127         /* Try with default provider */
128         provider = pollcb_provider(pollset_default_method);
129         if (!provider) {
130             return APR_ENOTIMPL;
131         }
132         rv = (*provider->create)(pollcb, size, p, flags);
133         if (rv != APR_SUCCESS) {
134             return rv;
135         }
136         pollcb->provider = provider;
137     }
138
139     *ret_pollcb = pollcb;
140     return APR_SUCCESS;
141 }
142
143 APR_DECLARE(apr_status_t) apr_pollcb_create(apr_pollcb_t **pollcb,
144                                             apr_uint32_t size,
145                                             apr_pool_t *p,
146                                             apr_uint32_t flags)
147 {
148     apr_pollset_method_e method = APR_POLLSET_DEFAULT;
149     return apr_pollcb_create_ex(pollcb, size, p, flags, method);
150 }
151
152 APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb,
153                                          apr_pollfd_t *descriptor)
154 {
155     return (*pollcb->provider->add)(pollcb, descriptor);
156 }
157
158 APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb,
159                                             apr_pollfd_t *descriptor)
160 {
161     return (*pollcb->provider->remove)(pollcb, descriptor);
162 }
163
164
165 APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb,
166                                           apr_interval_time_t timeout,
167                                           apr_pollcb_cb_t func,
168                                           void *baton)
169 {
170     return (*pollcb->provider->poll)(pollcb, timeout, func, baton);
171 }