]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/apr/poll/unix/pollcb.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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_AIO_MSGQ:
70         case APR_POLLSET_DEFAULT:
71         break;
72     }
73     return provider;
74 }
75
76 APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **ret_pollcb,
77                                                apr_uint32_t size,
78                                                apr_pool_t *p,
79                                                apr_uint32_t flags,
80                                                apr_pollset_method_e method)
81 {
82     apr_status_t rv;
83     apr_pollcb_t *pollcb;
84     apr_pollcb_provider_t *provider = NULL;
85
86     *ret_pollcb = NULL;
87
88  #ifdef WIN32
89     /* This will work only if ws2_32.dll has WSAPoll funtion.
90      * We could check the presence of the function here,
91      * but someone might implement other pollcb method in
92      * the future.
93      */
94     if (method == APR_POLLSET_DEFAULT) {
95         method = APR_POLLSET_POLL;
96     }
97  #endif
98
99     if (method == APR_POLLSET_DEFAULT)
100         method = pollset_default_method;
101     while (provider == NULL) {
102         provider = pollcb_provider(method);
103         if (!provider) {
104             if ((flags & APR_POLLSET_NODEFAULT) == APR_POLLSET_NODEFAULT)
105                 return APR_ENOTIMPL;
106             if (method == pollset_default_method)
107                 return APR_ENOTIMPL;
108             method = pollset_default_method;
109         }
110     }
111
112     pollcb = apr_palloc(p, sizeof(*pollcb));
113     pollcb->nelts = 0;
114     pollcb->nalloc = size;
115     pollcb->pool = p;
116     pollcb->provider = provider;
117
118     rv = (*provider->create)(pollcb, size, p, flags);
119     if (rv == APR_ENOTIMPL) {
120         if (method == pollset_default_method) {
121             return rv;
122         }
123
124         if ((flags & APR_POLLSET_NODEFAULT) == APR_POLLSET_NODEFAULT) {
125             return rv;
126         }
127
128         /* Try with default provider */
129         provider = pollcb_provider(pollset_default_method);
130         if (!provider) {
131             return APR_ENOTIMPL;
132         }
133         rv = (*provider->create)(pollcb, size, p, flags);
134         if (rv != APR_SUCCESS) {
135             return rv;
136         }
137         pollcb->provider = provider;
138     }
139
140     *ret_pollcb = pollcb;
141     return APR_SUCCESS;
142 }
143
144 APR_DECLARE(apr_status_t) apr_pollcb_create(apr_pollcb_t **pollcb,
145                                             apr_uint32_t size,
146                                             apr_pool_t *p,
147                                             apr_uint32_t flags)
148 {
149     apr_pollset_method_e method = APR_POLLSET_DEFAULT;
150     return apr_pollcb_create_ex(pollcb, size, p, flags, method);
151 }
152
153 APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb,
154                                          apr_pollfd_t *descriptor)
155 {
156     return (*pollcb->provider->add)(pollcb, descriptor);
157 }
158
159 APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb,
160                                             apr_pollfd_t *descriptor)
161 {
162     return (*pollcb->provider->remove)(pollcb, descriptor);
163 }
164
165
166 APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb,
167                                           apr_interval_time_t timeout,
168                                           apr_pollcb_cb_t func,
169                                           void *baton)
170 {
171     return (*pollcb->provider->poll)(pollcb, timeout, func, baton);
172 }