pollcb.c revision 286503
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: 69266735Speter case APR_POLLSET_AIO_MSGQ: 70251875Speter case APR_POLLSET_DEFAULT: 71251875Speter break; 72251875Speter } 73251875Speter return provider; 74251875Speter} 75251875Speter 76251875SpeterAPR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **ret_pollcb, 77251875Speter apr_uint32_t size, 78251875Speter apr_pool_t *p, 79251875Speter apr_uint32_t flags, 80251875Speter apr_pollset_method_e method) 81251875Speter{ 82251875Speter apr_status_t rv; 83251875Speter apr_pollcb_t *pollcb; 84251875Speter apr_pollcb_provider_t *provider = NULL; 85251875Speter 86251875Speter *ret_pollcb = NULL; 87251875Speter 88251875Speter #ifdef WIN32 89251875Speter /* This will work only if ws2_32.dll has WSAPoll funtion. 90251875Speter * We could check the presence of the function here, 91251875Speter * but someone might implement other pollcb method in 92251875Speter * the future. 93251875Speter */ 94251875Speter if (method == APR_POLLSET_DEFAULT) { 95251875Speter method = APR_POLLSET_POLL; 96251875Speter } 97251875Speter #endif 98251875Speter 99251875Speter if (method == APR_POLLSET_DEFAULT) 100251875Speter method = pollset_default_method; 101251875Speter while (provider == NULL) { 102251875Speter provider = pollcb_provider(method); 103251875Speter if (!provider) { 104251875Speter if ((flags & APR_POLLSET_NODEFAULT) == APR_POLLSET_NODEFAULT) 105251875Speter return APR_ENOTIMPL; 106251875Speter if (method == pollset_default_method) 107251875Speter return APR_ENOTIMPL; 108251875Speter method = pollset_default_method; 109251875Speter } 110251875Speter } 111251875Speter 112251875Speter pollcb = apr_palloc(p, sizeof(*pollcb)); 113251875Speter pollcb->nelts = 0; 114251875Speter pollcb->nalloc = size; 115251875Speter pollcb->pool = p; 116251875Speter pollcb->provider = provider; 117251875Speter 118251875Speter rv = (*provider->create)(pollcb, size, p, flags); 119251875Speter if (rv == APR_ENOTIMPL) { 120251875Speter if (method == pollset_default_method) { 121251875Speter return rv; 122251875Speter } 123251875Speter 124251875Speter if ((flags & APR_POLLSET_NODEFAULT) == APR_POLLSET_NODEFAULT) { 125251875Speter return rv; 126251875Speter } 127251875Speter 128251875Speter /* Try with default provider */ 129251875Speter provider = pollcb_provider(pollset_default_method); 130251875Speter if (!provider) { 131251875Speter return APR_ENOTIMPL; 132251875Speter } 133251875Speter rv = (*provider->create)(pollcb, size, p, flags); 134251875Speter if (rv != APR_SUCCESS) { 135251875Speter return rv; 136251875Speter } 137251875Speter pollcb->provider = provider; 138251875Speter } 139286503Speter else if (rv != APR_SUCCESS) { 140286503Speter return rv; 141286503Speter } 142251875Speter 143251875Speter *ret_pollcb = pollcb; 144251875Speter return APR_SUCCESS; 145251875Speter} 146251875Speter 147251875SpeterAPR_DECLARE(apr_status_t) apr_pollcb_create(apr_pollcb_t **pollcb, 148251875Speter apr_uint32_t size, 149251875Speter apr_pool_t *p, 150251875Speter apr_uint32_t flags) 151251875Speter{ 152251875Speter apr_pollset_method_e method = APR_POLLSET_DEFAULT; 153251875Speter return apr_pollcb_create_ex(pollcb, size, p, flags, method); 154251875Speter} 155251875Speter 156251875SpeterAPR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb, 157251875Speter apr_pollfd_t *descriptor) 158251875Speter{ 159251875Speter return (*pollcb->provider->add)(pollcb, descriptor); 160251875Speter} 161251875Speter 162251875SpeterAPR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb, 163251875Speter apr_pollfd_t *descriptor) 164251875Speter{ 165251875Speter return (*pollcb->provider->remove)(pollcb, descriptor); 166251875Speter} 167251875Speter 168251875Speter 169251875SpeterAPR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, 170251875Speter apr_interval_time_t timeout, 171251875Speter apr_pollcb_cb_t func, 172251875Speter void *baton) 173251875Speter{ 174251875Speter return (*pollcb->provider->poll)(pollcb, timeout, func, baton); 175251875Speter} 176