1251875Speter/* Licensed to the Apache Software Foundation (ASF) under one or more 2251875Speter * contributor license agreements. See the NOTICE file distributed with 3251875Speter * this work for additional information regarding copyright ownership. 4251875Speter * The ASF licenses this file to You under the Apache License, Version 2.0 5251875Speter * (the "License"); you may not use this file except in compliance with 6251875Speter * the License. You may obtain a copy of the License at 7251875Speter * 8251875Speter * http://www.apache.org/licenses/LICENSE-2.0 9251875Speter * 10251875Speter * Unless required by applicable law or agreed to in writing, software 11251875Speter * distributed under the License is distributed on an "AS IS" BASIS, 12251875Speter * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13251875Speter * See the License for the specific language governing permissions and 14251875Speter * limitations under the License. 15251875Speter */ 16251875Speter 17251875Speter#ifdef WIN32 18251875Speter/* POSIX defines 1024 for the FD_SETSIZE */ 19251875Speter#define FD_SETSIZE 1024 20251875Speter#endif 21251875Speter 22251875Speter#include "apr.h" 23251875Speter#include "apr_poll.h" 24251875Speter#include "apr_time.h" 25251875Speter#include "apr_portable.h" 26251875Speter#include "apr_arch_file_io.h" 27251875Speter#include "apr_arch_networkio.h" 28251875Speter#include "apr_arch_poll_private.h" 29251875Speter 30251875Speterstatic apr_pollset_method_e pollset_default_method = POLLSET_DEFAULT_METHOD; 31251875Speter#if defined(HAVE_KQUEUE) 32251875Speterextern apr_pollcb_provider_t *apr_pollcb_provider_kqueue; 33251875Speter#endif 34251875Speter#if defined(HAVE_PORT_CREATE) 35251875Speterextern apr_pollcb_provider_t *apr_pollcb_provider_port; 36251875Speter#endif 37251875Speter#if defined(HAVE_EPOLL) 38251875Speterextern apr_pollcb_provider_t *apr_pollcb_provider_epoll; 39251875Speter#endif 40251875Speter#if defined(HAVE_POLL) 41251875Speterextern apr_pollcb_provider_t *apr_pollcb_provider_poll; 42251875Speter#endif 43251875Speter 44251875Speterstatic apr_pollcb_provider_t *pollcb_provider(apr_pollset_method_e method) 45251875Speter{ 46251875Speter apr_pollcb_provider_t *provider = NULL; 47251875Speter switch (method) { 48251875Speter case APR_POLLSET_KQUEUE: 49251875Speter#if defined(HAVE_KQUEUE) 50251875Speter provider = apr_pollcb_provider_kqueue; 51251875Speter#endif 52251875Speter break; 53251875Speter case APR_POLLSET_PORT: 54251875Speter#if defined(HAVE_PORT_CREATE) 55251875Speter provider = apr_pollcb_provider_port; 56251875Speter#endif 57251875Speter break; 58251875Speter case APR_POLLSET_EPOLL: 59251875Speter#if defined(HAVE_EPOLL) 60251875Speter provider = apr_pollcb_provider_epoll; 61251875Speter#endif 62251875Speter break; 63251875Speter case APR_POLLSET_POLL: 64251875Speter#if defined(HAVE_POLL) 65251875Speter provider = apr_pollcb_provider_poll; 66251875Speter#endif 67251875Speter break; 68251875Speter case APR_POLLSET_SELECT: 69251875Speter case APR_POLLSET_DEFAULT: 70251875Speter break; 71251875Speter } 72251875Speter return provider; 73251875Speter} 74251875Speter 75251875SpeterAPR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **ret_pollcb, 76251875Speter apr_uint32_t size, 77251875Speter apr_pool_t *p, 78251875Speter apr_uint32_t flags, 79251875Speter apr_pollset_method_e method) 80251875Speter{ 81251875Speter apr_status_t rv; 82251875Speter apr_pollcb_t *pollcb; 83251875Speter apr_pollcb_provider_t *provider = NULL; 84251875Speter 85251875Speter *ret_pollcb = NULL; 86251875Speter 87251875Speter #ifdef WIN32 88251875Speter /* This will work only if ws2_32.dll has WSAPoll funtion. 89251875Speter * We could check the presence of the function here, 90251875Speter * but someone might implement other pollcb method in 91251875Speter * the future. 92251875Speter */ 93251875Speter if (method == APR_POLLSET_DEFAULT) { 94251875Speter method = APR_POLLSET_POLL; 95251875Speter } 96251875Speter #endif 97251875Speter 98251875Speter if (method == APR_POLLSET_DEFAULT) 99251875Speter method = pollset_default_method; 100251875Speter while (provider == NULL) { 101251875Speter provider = pollcb_provider(method); 102251875Speter if (!provider) { 103251875Speter if ((flags & APR_POLLSET_NODEFAULT) == APR_POLLSET_NODEFAULT) 104251875Speter return APR_ENOTIMPL; 105251875Speter if (method == pollset_default_method) 106251875Speter return APR_ENOTIMPL; 107251875Speter method = pollset_default_method; 108251875Speter } 109251875Speter } 110251875Speter 111251875Speter pollcb = apr_palloc(p, sizeof(*pollcb)); 112251875Speter pollcb->nelts = 0; 113251875Speter pollcb->nalloc = size; 114251875Speter pollcb->pool = p; 115251875Speter pollcb->provider = provider; 116251875Speter 117251875Speter rv = (*provider->create)(pollcb, size, p, flags); 118251875Speter if (rv == APR_ENOTIMPL) { 119251875Speter if (method == pollset_default_method) { 120251875Speter return rv; 121251875Speter } 122251875Speter 123251875Speter if ((flags & APR_POLLSET_NODEFAULT) == APR_POLLSET_NODEFAULT) { 124251875Speter return rv; 125251875Speter } 126251875Speter 127251875Speter /* Try with default provider */ 128251875Speter provider = pollcb_provider(pollset_default_method); 129251875Speter if (!provider) { 130251875Speter return APR_ENOTIMPL; 131251875Speter } 132251875Speter rv = (*provider->create)(pollcb, size, p, flags); 133251875Speter if (rv != APR_SUCCESS) { 134251875Speter return rv; 135251875Speter } 136251875Speter pollcb->provider = provider; 137251875Speter } 138251875Speter 139251875Speter *ret_pollcb = pollcb; 140251875Speter return APR_SUCCESS; 141251875Speter} 142251875Speter 143251875SpeterAPR_DECLARE(apr_status_t) apr_pollcb_create(apr_pollcb_t **pollcb, 144251875Speter apr_uint32_t size, 145251875Speter apr_pool_t *p, 146251875Speter apr_uint32_t flags) 147251875Speter{ 148251875Speter apr_pollset_method_e method = APR_POLLSET_DEFAULT; 149251875Speter return apr_pollcb_create_ex(pollcb, size, p, flags, method); 150251875Speter} 151251875Speter 152251875SpeterAPR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb, 153251875Speter apr_pollfd_t *descriptor) 154251875Speter{ 155251875Speter return (*pollcb->provider->add)(pollcb, descriptor); 156251875Speter} 157251875Speter 158251875SpeterAPR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb, 159251875Speter apr_pollfd_t *descriptor) 160251875Speter{ 161251875Speter return (*pollcb->provider->remove)(pollcb, descriptor); 162251875Speter} 163251875Speter 164251875Speter 165251875SpeterAPR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, 166251875Speter apr_interval_time_t timeout, 167251875Speter apr_pollcb_cb_t func, 168251875Speter void *baton) 169251875Speter{ 170251875Speter return (*pollcb->provider->poll)(pollcb, timeout, func, baton); 171251875Speter} 172