Return-Path: Delivered-To: apmail-apr-commits-archive@www.apache.org Received: (qmail 18931 invoked from network); 2 Oct 2009 23:29:18 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 2 Oct 2009 23:29:18 -0000 Received: (qmail 19132 invoked by uid 500); 2 Oct 2009 23:29:17 -0000 Delivered-To: apmail-apr-commits-archive@apr.apache.org Received: (qmail 19065 invoked by uid 500); 2 Oct 2009 23:29:17 -0000 Mailing-List: contact commits-help@apr.apache.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: Reply-To: dev@apr.apache.org List-Id: Delivered-To: mailing list commits@apr.apache.org Received: (qmail 19056 invoked by uid 99); 2 Oct 2009 23:29:17 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 02 Oct 2009 23:29:17 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 02 Oct 2009 23:29:13 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 8063C23888D0; Fri, 2 Oct 2009 23:28:52 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r821200 - in /apr/apr/branches/1.4.x/poll/unix: pollcb.c pollset.c Date: Fri, 02 Oct 2009 23:28:52 -0000 To: commits@apr.apache.org From: jim@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20091002232852.8063C23888D0@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: jim Date: Fri Oct 2 23:28:51 2009 New Revision: 821200 URL: http://svn.apache.org/viewvc?rev=821200&view=rev Log: Finish backport of poll changes from trunk. Added: apr/apr/branches/1.4.x/poll/unix/pollcb.c (with props) apr/apr/branches/1.4.x/poll/unix/pollset.c (with props) Added: apr/apr/branches/1.4.x/poll/unix/pollcb.c URL: http://svn.apache.org/viewvc/apr/apr/branches/1.4.x/poll/unix/pollcb.c?rev=821200&view=auto ============================================================================== --- apr/apr/branches/1.4.x/poll/unix/pollcb.c (added) +++ apr/apr/branches/1.4.x/poll/unix/pollcb.c Fri Oct 2 23:28:51 2009 @@ -0,0 +1,166 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef WIN32 +/* POSIX defines 1024 for the FD_SETSIZE */ +#define FD_SETSIZE 1024 +#endif + +#include "apr.h" +#include "apr_poll.h" +#include "apr_time.h" +#include "apr_portable.h" +#include "apr_arch_file_io.h" +#include "apr_arch_networkio.h" +#include "apr_arch_poll_private.h" + +static apr_pollset_method_e pollset_default_method = POLLSET_DEFAULT_METHOD; +#if defined(HAVE_KQUEUE) +extern apr_pollcb_provider_t *apr_pollcb_provider_kqueue; +#endif +#if defined(HAVE_PORT_CREATE) +extern apr_pollcb_provider_t *apr_pollcb_provider_port; +#endif +#if defined(HAVE_EPOLL) +extern apr_pollcb_provider_t *apr_pollcb_provider_epoll; +#endif +#if defined(HAVE_POLL) +extern apr_pollcb_provider_t *apr_pollcb_provider_poll; +#endif + +static apr_pollcb_provider_t *pollcb_provider(apr_pollset_method_e method) +{ + apr_pollcb_provider_t *provider = NULL; + switch (method) { + case APR_POLLSET_KQUEUE: +#if defined(HAVE_KQUEUE) + provider = apr_pollcb_provider_kqueue; +#endif + break; + case APR_POLLSET_PORT: +#if defined(HAVE_PORT_CREATE) + provider = apr_pollcb_provider_port; +#endif + break; + case APR_POLLSET_EPOLL: +#if defined(HAVE_EPOLL) + provider = apr_pollcb_provider_epoll; +#endif + break; + case APR_POLLSET_POLL: +#if defined(HAVE_POLL) + provider = apr_pollcb_provider_poll; +#endif + break; + case APR_POLLSET_SELECT: + case APR_POLLSET_DEFAULT: + break; + } + return provider; +} + +APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **pollcb, + apr_uint32_t size, + apr_pool_t *p, + apr_uint32_t flags, + apr_pollset_method_e method) +{ + apr_status_t rv; + apr_pollcb_provider_t *provider = NULL; + + if (method == APR_POLLSET_DEFAULT) + method = pollset_default_method; + while (provider == NULL) { + provider = pollcb_provider(method); + if (!provider) { + *pollcb = NULL; + if ((flags & APR_POLLSET_NODEFAULT) == APR_POLLSET_NODEFAULT) + return APR_ENOTIMPL; + if (method == pollset_default_method) + return APR_ENOTIMPL; + method = pollset_default_method; + } + } + + *pollcb = apr_palloc(p, sizeof(**pollcb)); + (*pollcb)->nelts = 0; + (*pollcb)->nalloc = size; + (*pollcb)->pool = p; + (*pollcb)->provider = provider; + + rv = (*provider->create)(*pollcb, size, p, flags); + if (rv == APR_ENOTIMPL) { + *pollcb = NULL; + if (method == pollset_default_method) { + return rv; + } + + if ((flags & APR_POLLSET_NODEFAULT) == APR_POLLSET_NODEFAULT) { + return rv; + } + + /* Try with default provider */ + provider = pollcb_provider(pollset_default_method); + if (!provider) { + return APR_ENOTIMPL; + } + rv = (*provider->create)(*pollcb, size, p, flags); + if (rv != APR_SUCCESS) { + return rv; + } + (*pollcb)->provider = provider; + } + + return APR_SUCCESS; +} + +APR_DECLARE(apr_status_t) apr_pollcb_create(apr_pollcb_t **pollcb, + apr_uint32_t size, + apr_pool_t *p, + apr_uint32_t flags) +{ + apr_pollset_method_e method = APR_POLLSET_DEFAULT; + #ifdef WIN32 + /* This will work only if ws2_32.dll has WSAPoll funtion. + * We could check the presence of the function here, + * but someone might implement other pollcb method in + * the future. + */ + method = APR_POLLSET_POLL; + #endif + return apr_pollcb_create_ex(pollcb, size, p, flags, method); +} + +APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb, + apr_pollfd_t *descriptor) +{ + return (*pollcb->provider->add)(pollcb, descriptor); +} + +APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb, + apr_pollfd_t *descriptor) +{ + return (*pollcb->provider->remove)(pollcb, descriptor); +} + + +APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, + apr_interval_time_t timeout, + apr_pollcb_cb_t func, + void *baton) +{ + return (*pollcb->provider->poll)(pollcb, timeout, func, baton); +} Propchange: apr/apr/branches/1.4.x/poll/unix/pollcb.c ------------------------------------------------------------------------------ svn:eol-style = native Added: apr/apr/branches/1.4.x/poll/unix/pollset.c URL: http://svn.apache.org/viewvc/apr/apr/branches/1.4.x/poll/unix/pollset.c?rev=821200&view=auto ============================================================================== --- apr/apr/branches/1.4.x/poll/unix/pollset.c (added) +++ apr/apr/branches/1.4.x/poll/unix/pollset.c Fri Oct 2 23:28:51 2009 @@ -0,0 +1,347 @@ +/* Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef WIN32 +/* POSIX defines 1024 for the FD_SETSIZE */ +#define FD_SETSIZE 1024 +#endif + +#include "apr.h" +#include "apr_poll.h" +#include "apr_time.h" +#include "apr_portable.h" +#include "apr_arch_file_io.h" +#include "apr_arch_networkio.h" +#include "apr_arch_poll_private.h" +#include "apr_arch_inherit.h" + +static apr_pollset_method_e pollset_default_method = POLLSET_DEFAULT_METHOD; + +#if !APR_FILES_AS_SOCKETS +#if defined (WIN32) + +extern apr_status_t +apr_file_socket_pipe_create(apr_file_t **in, + apr_file_t **out, + apr_pool_t *p); + +extern apr_status_t +apr_file_socket_pipe_close(apr_file_t *file); + +/* Create a dummy wakeup socket pipe for interrupting the poller + */ +static apr_status_t create_wakeup_pipe(apr_pollset_t *pollset) +{ + apr_status_t rv; + apr_pollfd_t fd; + + if ((rv = apr_file_socket_pipe_create(&pollset->wakeup_pipe[0], + &pollset->wakeup_pipe[1], + pollset->pool)) != APR_SUCCESS) + return rv; + fd.reqevents = APR_POLLIN; + fd.desc_type = APR_POLL_FILE; + fd.desc.f = pollset->wakeup_pipe[0]; + /* Add the pipe to the pollset + */ + return apr_pollset_add(pollset, &fd); +} + +#else /* !WIN32 */ +static apr_status_t create_wakeup_pipe(apr_pollset_t *pollset) +{ + return APR_ENOTIMPL; +} + +static apr_status_t apr_file_socket_pipe_close(apr_file_t *file) +{ + return APR_ENOTIMPL; +} + +#endif /* WIN32 */ +#else /* APR_FILES_AS_SOCKETS */ + +/* Create a dummy wakeup pipe for interrupting the poller + */ +static apr_status_t create_wakeup_pipe(apr_pollset_t *pollset) +{ + apr_status_t rv; + apr_pollfd_t fd; + + if ((rv = apr_file_pipe_create(&pollset->wakeup_pipe[0], + &pollset->wakeup_pipe[1], + pollset->pool)) != APR_SUCCESS) + return rv; + fd.reqevents = APR_POLLIN; + fd.desc_type = APR_POLL_FILE; + fd.desc.f = pollset->wakeup_pipe[0]; + + { + int flags; + + if ((flags = fcntl(pollset->wakeup_pipe[0]->filedes, F_GETFD)) == -1) + return errno; + + flags |= FD_CLOEXEC; + if (fcntl(pollset->wakeup_pipe[0]->filedes, F_SETFD, flags) == -1) + return errno; + } + { + int flags; + + if ((flags = fcntl(pollset->wakeup_pipe[1]->filedes, F_GETFD)) == -1) + return errno; + + flags |= FD_CLOEXEC; + if (fcntl(pollset->wakeup_pipe[1]->filedes, F_SETFD, flags) == -1) + return errno; + } + + /* Add the pipe to the pollset + */ + return apr_pollset_add(pollset, &fd); +} +#endif /* !APR_FILES_AS_SOCKETS */ + +/* Read and discard what's ever in the wakeup pipe. + */ +void apr_pollset_drain_wakeup_pipe(apr_pollset_t *pollset) +{ + char rb[512]; + apr_size_t nr = sizeof(rb); + + while (apr_file_read(pollset->wakeup_pipe[0], rb, &nr) == APR_SUCCESS) { + /* Although we write just one byte to the other end of the pipe + * during wakeup, multiple treads could call the wakeup. + * So simply drain out from the input side of the pipe all + * the data. + */ + if (nr != sizeof(rb)) + break; + } +} + +static apr_status_t pollset_cleanup(void *p) +{ + apr_pollset_t *pollset = (apr_pollset_t *) p; + if (pollset->provider->cleanup) { + (*pollset->provider->cleanup)(pollset); + } + if (pollset->flags & APR_POLLSET_WAKEABLE) { + /* Close both sides of the wakeup pipe */ + if (pollset->wakeup_pipe[0]) { +#if APR_FILES_AS_SOCKETS + apr_file_close(pollset->wakeup_pipe[0]); +#else + apr_file_socket_pipe_close(pollset->wakeup_pipe[0]); +#endif + pollset->wakeup_pipe[0] = NULL; + } + if (pollset->wakeup_pipe[1]) { +#if APR_FILES_AS_SOCKETS + apr_file_close(pollset->wakeup_pipe[1]); +#else + apr_file_socket_pipe_close(pollset->wakeup_pipe[1]); +#endif + pollset->wakeup_pipe[1] = NULL; + } + } + + return APR_SUCCESS; +} + +#if defined(HAVE_KQUEUE) +extern apr_pollset_provider_t *apr_pollset_provider_kqueue; +#endif +#if defined(HAVE_PORT_CREATE) +extern apr_pollset_provider_t *apr_pollset_provider_port; +#endif +#if defined(HAVE_EPOLL) +extern apr_pollset_provider_t *apr_pollset_provider_epoll; +#endif +#if defined(HAVE_POLL) +extern apr_pollset_provider_t *apr_pollset_provider_poll; +#endif +extern apr_pollset_provider_t *apr_pollset_provider_select; + +static apr_pollset_provider_t *pollset_provider(apr_pollset_method_e method) +{ + apr_pollset_provider_t *provider = NULL; + switch (method) { + case APR_POLLSET_KQUEUE: +#if defined(HAVE_KQUEUE) + provider = apr_pollset_provider_kqueue; +#endif + break; + case APR_POLLSET_PORT: +#if defined(HAVE_PORT_CREATE) + provider = apr_pollset_provider_port; +#endif + break; + case APR_POLLSET_EPOLL: +#if defined(HAVE_EPOLL) + provider = apr_pollset_provider_epoll; +#endif + break; + case APR_POLLSET_POLL: +#if defined(HAVE_POLL) + provider = apr_pollset_provider_poll; +#endif + break; + case APR_POLLSET_SELECT: + provider = apr_pollset_provider_select; + break; + case APR_POLLSET_DEFAULT: + break; + } + return provider; +} + +APR_DECLARE(apr_status_t) apr_pollset_create_ex(apr_pollset_t **pollset, + apr_uint32_t size, + apr_pool_t *p, + apr_uint32_t flags, + apr_pollset_method_e method) +{ + apr_status_t rv; + apr_pollset_provider_t *provider = NULL; + + if (method == APR_POLLSET_DEFAULT) + method = pollset_default_method; + while (provider == NULL) { + provider = pollset_provider(method); + if (!provider) { + *pollset = NULL; + if ((flags & APR_POLLSET_NODEFAULT) == APR_POLLSET_NODEFAULT) + return APR_ENOTIMPL; + if (method == pollset_default_method) + return APR_ENOTIMPL; + method = pollset_default_method; + } + } + if (flags & APR_POLLSET_WAKEABLE) { + /* Add room for wakeup descriptor */ + size++; + } + + *pollset = apr_palloc(p, sizeof(**pollset)); + (*pollset)->nelts = 0; + (*pollset)->nalloc = size; + (*pollset)->pool = p; + (*pollset)->flags = flags; + (*pollset)->provider = provider; + + rv = (*provider->create)(*pollset, size, p, flags); + if (rv == APR_ENOTIMPL) { + if (method == pollset_default_method) { + *pollset = NULL; + return rv; + } + provider = pollset_provider(pollset_default_method); + if (!provider) { + *pollset = NULL; + return APR_ENOTIMPL; + } + rv = (*provider->create)(*pollset, size, p, flags); + if (rv != APR_SUCCESS) { + *pollset = NULL; + return rv; + } + (*pollset)->provider = provider; + } + if (flags & APR_POLLSET_WAKEABLE) { + /* Create wakeup pipe */ + if ((rv = create_wakeup_pipe(*pollset)) != APR_SUCCESS) { + *pollset = NULL; + return rv; + } + } + if ((flags & APR_POLLSET_WAKEABLE) || provider->cleanup) + apr_pool_cleanup_register(p, *pollset, pollset_cleanup, + apr_pool_cleanup_null); + return APR_SUCCESS; +} + +APR_DECLARE(const char *) apr_pollset_method_name(apr_pollset_t *pollset) +{ + return pollset->provider->name; +} + +APR_DECLARE(const char *) apr_poll_method_defname() +{ + apr_pollset_provider_t *provider = NULL; + + provider = pollset_provider(pollset_default_method); + if (provider) + return provider->name; + else + return "unknown"; +} + +APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset, + apr_uint32_t size, + apr_pool_t *p, + apr_uint32_t flags) +{ + apr_pollset_method_e method = APR_POLLSET_DEFAULT; + #ifdef WIN32 + /* Favor WSAPoll if supported. + * This will work only if ws2_32.dll has WSAPoll funtion. + * In other cases it will fall back to select() method unless + * the APR_POLLSET_NODEFAULT is added to the flags. + */ + method = APR_POLLSET_POLL; + #endif + return apr_pollset_create_ex(pollset, size, p, flags, method); +} + +APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t * pollset) +{ + if (pollset->flags & APR_POLLSET_WAKEABLE || + pollset->provider->cleanup) + return apr_pool_cleanup_run(pollset->pool, pollset, + pollset_cleanup); + else + return APR_SUCCESS; +} + +APR_DECLARE(apr_status_t) apr_pollset_wakeup(apr_pollset_t *pollset) +{ + if (pollset->flags & APR_POLLSET_WAKEABLE) + return apr_file_putc(1, pollset->wakeup_pipe[1]); + else + return APR_EINIT; +} + +APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, + const apr_pollfd_t *descriptor) +{ + return (*pollset->provider->add)(pollset, descriptor); +} + +APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset, + const apr_pollfd_t *descriptor) +{ + return (*pollset->provider->remove)(pollset, descriptor); +} + +APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, + apr_interval_time_t timeout, + apr_int32_t *num, + const apr_pollfd_t **descriptors) +{ + return (*pollset->provider->poll)(pollset, timeout, num, descriptors); +} Propchange: apr/apr/branches/1.4.x/poll/unix/pollset.c ------------------------------------------------------------------------------ svn:eol-style = native