157416Smarkm/* Licensed to the Apache Software Foundation (ASF) under one or more 257416Smarkm * contributor license agreements. See the NOTICE file distributed with 357416Smarkm * this work for additional information regarding copyright ownership. 457416Smarkm * The ASF licenses this file to You under the Apache License, Version 2.0 557416Smarkm * (the "License"); you may not use this file except in compliance with 657416Smarkm * the License. You may obtain a copy of the License at 757416Smarkm * 857416Smarkm * http://www.apache.org/licenses/LICENSE-2.0 957416Smarkm * 1057416Smarkm * Unless required by applicable law or agreed to in writing, software 1157416Smarkm * distributed under the License is distributed on an "AS IS" BASIS, 1257416Smarkm * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1357416Smarkm * See the License for the specific language governing permissions and 1457416Smarkm * limitations under the License. 1557416Smarkm */ 1657416Smarkm 1757416Smarkm#ifdef WIN32 1857416Smarkm/* POSIX defines 1024 for the FD_SETSIZE */ 1957416Smarkm#define FD_SETSIZE 1024 2057416Smarkm#endif 2157416Smarkm 2257416Smarkm#include "apr.h" 2357416Smarkm#include "apr_poll.h" 2457416Smarkm#include "apr_time.h" 2557416Smarkm#include "apr_portable.h" 2657416Smarkm#include "apr_arch_file_io.h" 2757416Smarkm#include "apr_arch_networkio.h" 2857416Smarkm#include "apr_arch_poll_private.h" 2957416Smarkm 3057416Smarkmstatic apr_pollset_method_e pollset_default_method = POLLSET_DEFAULT_METHOD; 3157416Smarkm#if defined(HAVE_KQUEUE) 3257416Smarkmextern apr_pollcb_provider_t *apr_pollcb_provider_kqueue; 3357416Smarkm#endif 3457416Smarkm#if defined(HAVE_PORT_CREATE) 3557416Smarkmextern apr_pollcb_provider_t *apr_pollcb_provider_port; 3657416Smarkm#endif 3757416Smarkm#if defined(HAVE_EPOLL) 3857416Smarkmextern apr_pollcb_provider_t *apr_pollcb_provider_epoll; 3957416Smarkm#endif 40233294Sstas#if defined(HAVE_POLL) 4157416Smarkmextern apr_pollcb_provider_t *apr_pollcb_provider_poll; 4257416Smarkm#endif 4357416Smarkm 4457416Smarkmstatic apr_pollcb_provider_t *pollcb_provider(apr_pollset_method_e method) 4557416Smarkm{ 4657416Smarkm apr_pollcb_provider_t *provider = NULL; 4757416Smarkm switch (method) { 4857416Smarkm case APR_POLLSET_KQUEUE: 4957416Smarkm#if defined(HAVE_KQUEUE) 5057416Smarkm provider = apr_pollcb_provider_kqueue; 5157416Smarkm#endif 5257416Smarkm break; 5357416Smarkm case APR_POLLSET_PORT: 5457416Smarkm#if defined(HAVE_PORT_CREATE) 5557416Smarkm provider = apr_pollcb_provider_port; 5657416Smarkm#endif 5757416Smarkm break; 5857416Smarkm case APR_POLLSET_EPOLL: 5957416Smarkm#if defined(HAVE_EPOLL) 6057416Smarkm provider = apr_pollcb_provider_epoll; 6157416Smarkm#endif 6257416Smarkm break; 6357416Smarkm case APR_POLLSET_POLL: 6457416Smarkm#if defined(HAVE_POLL) 6557416Smarkm provider = apr_pollcb_provider_poll; 6657416Smarkm#endif 6757416Smarkm break; 6857416Smarkm case APR_POLLSET_SELECT: 6957416Smarkm case APR_POLLSET_AIO_MSGQ: 7057416Smarkm case APR_POLLSET_DEFAULT: 7157416Smarkm break; 7257416Smarkm } 7357416Smarkm return provider; 7457416Smarkm} 7557416Smarkm 7657416SmarkmAPR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **ret_pollcb, 7757416Smarkm apr_uint32_t size, 7857416Smarkm apr_pool_t *p, 7957416Smarkm apr_uint32_t flags, 8057416Smarkm apr_pollset_method_e method) 8157416Smarkm{ 8257416Smarkm apr_status_t rv; 8357416Smarkm apr_pollcb_t *pollcb; 8457416Smarkm apr_pollcb_provider_t *provider = NULL; 8557416Smarkm 8657416Smarkm *ret_pollcb = NULL; 8757416Smarkm 8857416Smarkm #ifdef WIN32 8957416Smarkm /* This will work only if ws2_32.dll has WSAPoll funtion. 9057416Smarkm * We could check the presence of the function here, 9157416Smarkm * but someone might implement other pollcb method in 9257416Smarkm * the future. 9357416Smarkm */ 9457416Smarkm if (method == APR_POLLSET_DEFAULT) { 9557416Smarkm method = APR_POLLSET_POLL; 9657416Smarkm } 9757416Smarkm #endif 9857416Smarkm 9957416Smarkm if (method == APR_POLLSET_DEFAULT) 10057416Smarkm method = pollset_default_method; 10157416Smarkm while (provider == NULL) { 10257416Smarkm provider = pollcb_provider(method); 10357416Smarkm if (!provider) { 10457416Smarkm if ((flags & APR_POLLSET_NODEFAULT) == APR_POLLSET_NODEFAULT) 10557416Smarkm return APR_ENOTIMPL; 10657416Smarkm if (method == pollset_default_method) 10757416Smarkm return APR_ENOTIMPL; 10857416Smarkm method = pollset_default_method; 10957416Smarkm } 11057416Smarkm } 11157416Smarkm 11257416Smarkm pollcb = apr_palloc(p, sizeof(*pollcb)); 11357416Smarkm pollcb->nelts = 0; 11457416Smarkm pollcb->nalloc = size; 11557416Smarkm pollcb->pool = p; 11657416Smarkm pollcb->provider = provider; 11757416Smarkm 11857416Smarkm rv = (*provider->create)(pollcb, size, p, flags); 11957416Smarkm if (rv == APR_ENOTIMPL) { 12057416Smarkm if (method == pollset_default_method) { 12157416Smarkm return rv; 12257416Smarkm } 12357416Smarkm 12457416Smarkm if ((flags & APR_POLLSET_NODEFAULT) == APR_POLLSET_NODEFAULT) { 12557416Smarkm return rv; 12657416Smarkm } 12757416Smarkm 12857416Smarkm /* Try with default provider */ 12957416Smarkm provider = pollcb_provider(pollset_default_method); 13057416Smarkm if (!provider) { 13157416Smarkm return APR_ENOTIMPL; 13257416Smarkm } 13357416Smarkm rv = (*provider->create)(pollcb, size, p, flags); 13457416Smarkm if (rv != APR_SUCCESS) { 13557416Smarkm return rv; 13657416Smarkm } 13757416Smarkm pollcb->provider = provider; 13857416Smarkm } 13957416Smarkm 14057416Smarkm *ret_pollcb = pollcb; 14157416Smarkm return APR_SUCCESS; 14257416Smarkm} 14357416Smarkm 14457416SmarkmAPR_DECLARE(apr_status_t) apr_pollcb_create(apr_pollcb_t **pollcb, 14557416Smarkm apr_uint32_t size, 14657416Smarkm apr_pool_t *p, 14757416Smarkm apr_uint32_t flags) 14857416Smarkm{ 14957416Smarkm apr_pollset_method_e method = APR_POLLSET_DEFAULT; 15057416Smarkm return apr_pollcb_create_ex(pollcb, size, p, flags, method); 15157416Smarkm} 15257416Smarkm 15357416SmarkmAPR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb, 15457416Smarkm apr_pollfd_t *descriptor) 15557416Smarkm{ 15657416Smarkm return (*pollcb->provider->add)(pollcb, descriptor); 15757416Smarkm} 15857416Smarkm 15957416SmarkmAPR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb, 16057416Smarkm apr_pollfd_t *descriptor) 16157416Smarkm{ 16257416Smarkm return (*pollcb->provider->remove)(pollcb, descriptor); 16357416Smarkm} 16457416Smarkm 16557416Smarkm 16657416SmarkmAPR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, 16757416Smarkm apr_interval_time_t timeout, 16857416Smarkm apr_pollcb_cb_t func, 16957416Smarkm void *baton) 17057416Smarkm{ 17157416Smarkm return (*pollcb->provider->poll)(pollcb, timeout, func, baton); 17257416Smarkm} 17357416Smarkm