apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pque...@apache.org
Subject svn commit: r105905 - in apr/apr/trunk: . include include/arch/unix poll/unix
Date Sat, 20 Nov 2004 00:28:20 GMT
Author: pquerna
Date: Fri Nov 19 16:28:19 2004
New Revision: 105905

Added:
   apr/apr/trunk/include/arch/unix/apr_arch_poll_private.h   (contents, props changed)
   apr/apr/trunk/poll/unix/epoll.c   (contents, props changed)
   apr/apr/trunk/poll/unix/kqueue.c   (contents, props changed)
   apr/apr/trunk/poll/unix/select.c   (contents, props changed)
Modified:
   apr/apr/trunk/CHANGES
   apr/apr/trunk/include/apr_poll.h
   apr/apr/trunk/poll/unix/poll.c
Log:
This commit may break the win32 or netware builds because of the added files.

Added the APR_POLLSET_THREADSAFE flag for apr_pollset_create(). 
The flag is only supported by the KQueue or EPoll backends at this time.
All others should return ENOTIMPL.

Split poll/unix/poll.c into one file for each backend to better maintain them.

Tested On: FreeBSD 5.2.1, Linux 2.6 and OS X 10.3.6.


Modified: apr/apr/trunk/CHANGES
==============================================================================
--- apr/apr/trunk/CHANGES	(original)
+++ apr/apr/trunk/CHANGES	Fri Nov 19 16:28:19 2004
@@ -5,6 +5,13 @@
      and upgrading it to do SHA-256. Not yet ready for prime time.
      [Ben Laurie]
 
+  *) Added the APR_POLLSET_THREADSAFE flag. This allows multiple threads
+     to call the Pollset Add or Remove functions in a thread safe manner.
+     Currently only EPoll and KQueue support this flag. [Paul Querna]
+
+  *) Split poll/unix/poll.c into separate files for each Poll or Pollset 
+     implementation. [Paul Querna]
+
   *) Rewrite apr_file_printf to handle arbitrary length strings.
      PR 28029.  [Chris Knight <Christopher.D.Knight nasa.gov>,
      Garrett Rooney <rooneg electricjellyfish.net>]

Modified: apr/apr/trunk/include/apr_poll.h
==============================================================================
--- apr/apr/trunk/include/apr_poll.h	(original)
+++ apr/apr/trunk/include/apr_poll.h	Fri Nov 19 16:28:19 2004
@@ -50,6 +50,11 @@
 #define APR_POLLHUP   0x020     /**< Hangup occurred */
 #define APR_POLLNVAL  0x040     /**< Descriptior invalid */
 
+/**
+ * Pollset Flags
+ */
+#define APR_POLLSET_THREADSAFE 0x001 /**< Adding or Removing a Descriptor is thread safe */
+
 /** Used in apr_pollfd_t to determine what the apr_descriptor is */
 typedef enum { 
     APR_NO_DESC,                /**< nothing here */

Added: apr/apr/trunk/include/arch/unix/apr_arch_poll_private.h
==============================================================================
--- (empty file)
+++ apr/apr/trunk/include/arch/unix/apr_arch_poll_private.h	Fri Nov 19 16:28:19 2004
@@ -0,0 +1,92 @@
+/* Copyright 2000-2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+#ifndef APR_ARCH_POLL_PRIVATE_H
+#define APR_ARCH_POLL_PRIVATE_H
+
+#include "apr.h"
+#include "apr_poll.h"
+#include "apr_time.h"
+#include "apr_portable.h"
+#include "apr_arch_networkio.h"
+#include "apr_arch_file_io.h"
+
+#if HAVE_POLL_H
+#include <poll.h>
+#endif
+
+#if HAVE_SYS_POLL_H
+#include <sys/poll.h>
+#endif
+
+#ifdef HAVE_KQUEUE
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_EPOLL
+#include <sys/epoll.h>
+#endif
+
+#ifdef NETWARE
+#define HAS_SOCKETS(dt) (dt == APR_POLL_SOCKET) ? 1 : 0
+#define HAS_PIPES(dt) (dt == APR_POLL_FILE) ? 1 : 0
+#endif
+
+/* Choose the best method platform specific to use in apr_pollset */
+#ifdef HAVE_KQUEUE
+#define POLLSET_USES_KQUEUE
+#elif defined(HAVE_EPOLL)
+#define POLLSET_USES_EPOLL
+#elif defined(HAVE_POLL)
+#define POLLSET_USES_POLL
+#else
+#define POLLSET_USES_SELECT
+#endif
+
+#ifdef HAVE_POLL
+#define POLL_USES_POLL
+#else
+#define POLL_USES_SELECT
+#endif
+
+#if defined(POLLSET_USES_KQUEUE) || defined(POLLSET_USES_EPOLL)
+
+#include "apr_ring.h"
+
+#if APR_HAS_THREADS
+#include "apr_thread_mutex.h"
+#define pollset_lock_rings() \
+    if(pollset->flags & APR_POLLSET_THREADSAFE) \
+        apr_thread_mutex_lock(pollset->ring_lock);
+#define pollset_unlock_rings() \
+    if(pollset->flags & APR_POLLSET_THREADSAFE) \
+        apr_thread_mutex_unlock(pollset->ring_lock);
+#else
+#define pollset_lock_rings()
+#define pollset_unlock_rings()
+#endif
+
+typedef struct pfd_elem_t pfd_elem_t;
+
+struct pfd_elem_t {
+    APR_RING_ENTRY(pfd_elem_t) link;
+    apr_pollfd_t pfd;
+};
+
+#endif
+
+#endif /* APR_ARCH_POLL_PRIVATE_H */

Added: apr/apr/trunk/poll/unix/epoll.c
==============================================================================
--- (empty file)
+++ apr/apr/trunk/poll/unix/epoll.c	Fri Nov 19 16:28:19 2004
@@ -0,0 +1,270 @@
+/* Copyright 2000-2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+#include "apr_arch_poll_private.h"
+
+#ifdef POLLSET_USES_EPOLL
+
+static apr_int16_t get_epoll_event(apr_int16_t event)
+{
+    apr_int16_t rv = 0;
+
+    if (event & APR_POLLIN)
+        rv |= EPOLLIN;
+    if (event & APR_POLLPRI)
+        rv |= EPOLLPRI;
+    if (event & APR_POLLOUT)
+        rv |= EPOLLOUT;
+    if (event & APR_POLLERR)
+        rv |= EPOLLERR;
+    if (event & APR_POLLHUP)
+        rv |= EPOLLHUP;
+    /* APR_POLLNVAL is not handled by epoll. */
+
+    return rv;
+}
+
+static apr_int16_t get_epoll_revent(apr_int16_t event)
+{
+    apr_int16_t rv = 0;
+
+    if (event & EPOLLIN)
+        rv |= APR_POLLIN;
+    if (event & EPOLLPRI)
+        rv |= APR_POLLPRI;
+    if (event & EPOLLOUT)
+        rv |= APR_POLLOUT;
+    if (event & EPOLLERR)
+        rv |= APR_POLLERR;
+    if (event & EPOLLHUP)
+        rv |= APR_POLLHUP;
+    /* APR_POLLNVAL is not handled by epoll. */
+
+    return rv;
+}
+
+struct apr_pollset_t
+{
+    apr_pool_t *pool;
+    apr_uint32_t nelts;
+    apr_uint32_t nalloc;
+    int epoll_fd;
+    struct epoll_event *pollset;
+    apr_pollfd_t *result_set;
+    apr_uint32_t flags;
+#if APR_HAS_THREADS
+    /* A thread mutex to protect operations on the rings */
+    apr_thread_mutex_t *ring_lock;
+#endif
+    /* A ring containing all of the pollfd_t that are active */
+    APR_RING_HEAD(pfd_query_ring_t, pfd_elem_t) query_ring;
+    /* A ring of pollfd_t that have been used, and then _remove()'d */
+    APR_RING_HEAD(pfd_free_ring_t, pfd_elem_t) free_ring;
+    /* A ring of pollfd_t where rings that have been _remove()`ed but
+        might still be inside a _poll() */
+    APR_RING_HEAD(pfd_dead_ring_t, pfd_elem_t) dead_ring;
+};
+
+static apr_status_t backend_cleanup(void *p_)
+{
+    apr_pollset_t *pollset = (apr_pollset_t *) p_;
+    close(pollset->epoll_fd);
+    return APR_SUCCESS;
+}
+
+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_status_t rv;
+
+    *pollset = apr_palloc(p, sizeof(**pollset));
+#if APR_HAS_THREADS
+    if (flags & APR_POLLSET_THREADSAFE &&
+        ((rv = apr_thread_mutex_create(&(*pollset)->ring_lock,
+                                       APR_THREAD_MUTEX_DEFAULT,
+                                       p) != APR_SUCCESS))) {
+        *pollset = NULL;
+        return rv;
+    }
+#else
+    if (flags & APR_POLLSET_THREADSAFE) {
+        *pollset = NULL;
+        return APR_ENOTIMPL;
+    }
+#endif
+    (*pollset)->nelts = 0;
+    (*pollset)->nalloc = size;
+    (*pollset)->flags = flags;
+    (*pollset)->pool = p;
+    (*pollset)->epoll_fd = epoll_create(size);
+    (*pollset)->pollset = apr_palloc(p, size * sizeof(struct epoll_event));
+    apr_pool_cleanup_register(p, (void *) (*pollset), backend_cleanup,
+                              apr_pool_cleanup_null);
+    (*pollset)->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
+
+    APR_RING_INIT(&(*pollset)->query_ring, pfd_elem_t, link);
+    APR_RING_INIT(&(*pollset)->free_ring, pfd_elem_t, link);
+    APR_RING_INIT(&(*pollset)->dead_ring, pfd_elem_t, link);
+
+    return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset)
+{
+    return apr_pool_cleanup_run(pollset->pool, pollset, backend_cleanup);
+}
+
+APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset,
+                                          const apr_pollfd_t *descriptor)
+{
+    struct epoll_event ev;
+    int ret = -1;
+    pfd_elem_t *elem;
+    apr_status_t rv = APR_SUCCESS;
+
+    pollset_lock_rings();
+
+    if (!APR_RING_EMPTY(&(pollset->free_ring), pfd_elem_t, link)) {
+        elem = APR_RING_FIRST(&(pollset->free_ring));
+        APR_RING_REMOVE(elem, link);
+    }
+    else {
+        elem = (pfd_elem_t *) apr_palloc(pollset->pool, sizeof(pfd_elem_t));
+        APR_RING_ELEM_INIT(elem, link);
+    }
+    elem->pfd = *descriptor;
+
+    ev.events = get_epoll_event(descriptor->reqevents);
+    ev.data.ptr = elem;
+    if (descriptor->desc_type == APR_POLL_SOCKET) {
+        ret = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_ADD,
+                        descriptor->desc.s->socketdes, &ev);
+    }
+    else {
+        ret = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_ADD,
+                        descriptor->desc.f->filedes, &ev);
+    }
+
+    if (0 != ret) {
+        rv = APR_EBADF;
+        APR_RING_INSERT_TAIL(&(pollset->free_ring), elem, pfd_elem_t, link);
+    }
+    else {
+        pollset->nelts++;
+        APR_RING_INSERT_TAIL(&(pollset->query_ring), elem, pfd_elem_t, link);
+    }
+
+    pollset_unlock_rings();
+
+    return rv;
+}
+
+APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
+                                             const apr_pollfd_t *descriptor)
+{
+    pfd_elem_t *ep;
+    apr_status_t rv = APR_SUCCESS;
+    struct epoll_event ev;
+    int ret = -1;
+
+    pollset_lock_rings();
+
+    ev.events = get_epoll_event(descriptor->reqevents);
+
+    if (descriptor->desc_type == APR_POLL_SOCKET) {
+        ret = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_DEL,
+                        descriptor->desc.s->socketdes, &ev);
+    }
+    else {
+        ret = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_DEL,
+                        descriptor->desc.f->filedes, &ev);
+    }
+    if (ret < 0) {
+        rv = APR_NOTFOUND;
+    }
+
+    if (!APR_RING_EMPTY(&(pollset->query_ring), pfd_elem_t, link)) {
+        for (ep = APR_RING_FIRST(&(pollset->query_ring));
+             ep != APR_RING_SENTINEL(&(pollset->query_ring),
+                                     pfd_elem_t, link);
+             ep = APR_RING_NEXT(ep, link)) {
+
+            if (descriptor->desc.s == ep->pfd.desc.s) {
+                APR_RING_REMOVE(ep, link);
+                APR_RING_INSERT_TAIL(&(pollset->dead_ring),
+                                     ep, pfd_elem_t, link);
+                break;
+            }
+        }
+    }
+
+    pollset_unlock_rings();
+
+    return rv;
+}
+
+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)
+{
+    int ret, i;
+    apr_status_t rv = APR_SUCCESS;
+    pfd_elem_t *ep;
+
+    if (timeout > 0) {
+        timeout /= 1000;
+    }
+
+    ret = epoll_wait(pollset->epoll_fd, pollset->pollset, pollset->nalloc,
+                     timeout);
+    (*num) = ret;
+
+    if (ret < 0) {
+        rv = apr_get_netos_error();
+    }
+    else if (ret == 0) {
+        rv = APR_TIMEUP;
+    }
+    else {
+        for (i = 0; i < ret; i++) {
+            pollset->result_set[i] =
+                (((pfd_elem_t *) (pollset->pollset[i].data.ptr))->pfd);
+            pollset->result_set[i].rtnevents =
+                get_epoll_revent(pollset->pollset[i].events);
+        }
+
+        if (descriptors) {
+            *descriptors = pollset->result_set;
+        }
+    }
+
+    pollset_lock_rings();
+
+    /* Shift all PFDs in the Dead Ring to be Free Ring */
+    while (!APR_RING_EMPTY(&(pollset->dead_ring), pfd_elem_t, link)) {
+        ep = APR_RING_FIRST(&(pollset->dead_ring));
+        APR_RING_REMOVE(ep, link);
+        APR_RING_INSERT_TAIL(&(pollset->free_ring), ep, pfd_elem_t, link);
+    }
+
+    pollset_unlock_rings();
+
+    return rv;
+}
+
+#endif /* POLLSET_USES_EPOLL */

Added: apr/apr/trunk/poll/unix/kqueue.c
==============================================================================
--- (empty file)
+++ apr/apr/trunk/poll/unix/kqueue.c	Fri Nov 19 16:28:19 2004
@@ -0,0 +1,288 @@
+/* Copyright 2000-2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+#include "apr_arch_poll_private.h"
+
+#ifdef POLLSET_USES_KQUEUE
+
+static apr_int16_t get_kqueue_revent(apr_int16_t event, apr_int16_t flags)
+{
+    apr_int16_t rv = 0;
+
+    if (event & EVFILT_READ)
+        rv |= APR_POLLIN;
+    if (event & EVFILT_WRITE)
+        rv |= APR_POLLOUT;
+    if (flags & EV_EOF)
+        rv |= APR_POLLHUP;
+    if (flags & EV_ERROR)
+        rv |= APR_POLLERR;
+
+    return rv;
+}
+
+struct apr_pollset_t
+{
+    apr_pool_t *pool;
+    apr_uint32_t nelts;
+    apr_uint32_t nalloc;
+    int kqueue_fd;
+    struct kevent kevent;
+    struct kevent *ke_set;
+    apr_pollfd_t *result_set;
+    apr_uint32_t flags;
+#if APR_HAS_THREADS
+    /* A thread mutex to protect operations on the rings */
+    apr_thread_mutex_t *ring_lock;
+#endif
+    /* A ring containing all of the pollfd_t that are active */
+    APR_RING_HEAD(pfd_query_ring_t, pfd_elem_t) query_ring;
+    /* A ring of pollfd_t that have been used, and then _remove'd */
+    APR_RING_HEAD(pfd_free_ring_t, pfd_elem_t) free_ring;
+    /* A ring of pollfd_t where rings that have been _remove'd but
+       might still be inside a _poll */
+    APR_RING_HEAD(pfd_dead_ring_t, pfd_elem_t) dead_ring;
+};
+
+static apr_status_t backend_cleanup(void *p_)
+{
+    apr_pollset_t *pollset = (apr_pollset_t *) p_;
+    close(pollset->kqueue_fd);
+    return APR_SUCCESS;
+}
+
+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_status_t rv = APR_SUCCESS;
+    *pollset = apr_palloc(p, sizeof(**pollset));
+#if APR_HAS_THREADS
+    if (flags & APR_POLLSET_THREADSAFE &&
+        ((rv = apr_thread_mutex_create(&(*pollset)->ring_lock,
+                                       APR_THREAD_MUTEX_DEFAULT,
+                                       p) != APR_SUCCESS))) {
+        *pollset = NULL;
+        return rv;
+    }
+#else
+    if (flags & APR_POLLSET_THREADSAFE) {
+        *pollset = NULL;
+        return APR_ENOTIMPL;
+    }
+#endif
+    (*pollset)->nelts = 0;
+    (*pollset)->nalloc = size;
+    (*pollset)->flags = flags;
+    (*pollset)->pool = p;
+
+    (*pollset)->ke_set =
+        (struct kevent *) apr_palloc(p, size * sizeof(struct kevent));
+
+    memset((*pollset)->ke_set, 0, size * sizeof(struct kevent));
+
+    (*pollset)->kqueue_fd = kqueue();
+
+    if ((*pollset)->kqueue_fd == -1) {
+        return APR_ENOMEM;
+    }
+
+    apr_pool_cleanup_register(p, (void *) (*pollset), backend_cleanup,
+                              apr_pool_cleanup_null);
+
+    (*pollset)->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
+
+    APR_RING_INIT(&(*pollset)->query_ring, pfd_elem_t, link);
+    APR_RING_INIT(&(*pollset)->free_ring, pfd_elem_t, link);
+    APR_RING_INIT(&(*pollset)->dead_ring, pfd_elem_t, link);
+
+    return rv;
+}
+
+APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t * pollset)
+{
+    return apr_pool_cleanup_run(pollset->pool, pollset, backend_cleanup);
+}
+
+APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset,
+                                          const apr_pollfd_t *descriptor)
+{
+    apr_os_sock_t fd;
+    pfd_elem_t *elem;
+    apr_status_t rv = APR_SUCCESS;
+
+    pollset_lock_rings();
+
+    if (!APR_RING_EMPTY(&(pollset->free_ring), pfd_elem_t, link)) {
+        elem = APR_RING_FIRST(&(pollset->free_ring));
+        APR_RING_REMOVE(elem, link);
+    }
+    else {
+        elem = (pfd_elem_t *) apr_palloc(pollset->pool, sizeof(pfd_elem_t));
+        APR_RING_ELEM_INIT(elem, link);
+    }
+    elem->pfd = *descriptor;
+
+    if (descriptor->desc_type == APR_POLL_SOCKET) {
+        fd = descriptor->desc.s->socketdes;
+    }
+    else {
+        fd = descriptor->desc.f->filedes;
+    }
+
+    if (descriptor->reqevents & APR_POLLIN) {
+        EV_SET(&pollset->kevent, fd, EVFILT_READ, EV_ADD, 0, 0, elem);
+
+        if (kevent(pollset->kqueue_fd, &pollset->kevent, 1, NULL, 0,
+                   NULL) == -1) {
+            rv = APR_ENOMEM;
+        }
+    }
+
+    if (descriptor->reqevents & APR_POLLOUT && rv == APR_SUCCESS) {
+        EV_SET(&pollset->kevent, fd, EVFILT_WRITE, EV_ADD, 0, 0, elem);
+
+        if (kevent(pollset->kqueue_fd, &pollset->kevent, 1, NULL, 0,
+                   NULL) == -1) {
+            rv = APR_ENOMEM;
+        }
+    }
+
+    if (rv == APR_SUCCESS) {
+        pollset->nelts++;
+        APR_RING_INSERT_TAIL(&(pollset->query_ring), elem, pfd_elem_t, link);
+    }
+    else {
+        APR_RING_INSERT_TAIL(&(pollset->free_ring), elem, pfd_elem_t, link);
+    }
+
+    pollset_unlock_rings();
+
+    return rv;
+}
+
+APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
+                                             const apr_pollfd_t *descriptor)
+{
+    pfd_elem_t *ep;
+    apr_status_t rv = APR_SUCCESS;
+    apr_os_sock_t fd;
+
+    pollset_lock_rings();
+
+    if (descriptor->desc_type == APR_POLL_SOCKET) {
+        fd = descriptor->desc.s->socketdes;
+    }
+    else {
+        fd = descriptor->desc.f->filedes;
+    }
+
+    if (descriptor->reqevents & APR_POLLIN) {
+        EV_SET(&pollset->kevent, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
+
+        if (kevent(pollset->kqueue_fd, &pollset->kevent, 1, NULL, 0,
+                   NULL) == -1) {
+            rv = APR_NOTFOUND;
+        }
+    }
+
+    if (descriptor->reqevents & APR_POLLOUT && rv == APR_SUCCESS) {
+        EV_SET(&pollset->kevent, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
+
+        if (kevent(pollset->kqueue_fd, &pollset->kevent, 1, NULL, 0,
+                   NULL) == -1) {
+            rv = APR_NOTFOUND;
+        }
+    }
+
+    if (!APR_RING_EMPTY(&(pollset->query_ring), pfd_elem_t, link)) {
+        for (ep = APR_RING_FIRST(&(pollset->query_ring));
+             ep != APR_RING_SENTINEL(&(pollset->query_ring),
+                                     pfd_elem_t, link);
+             ep = APR_RING_NEXT(ep, link)) {
+
+            if (descriptor->desc.s == ep->pfd.desc.s) {
+                APR_RING_REMOVE(ep, link);
+                APR_RING_INSERT_TAIL(&(pollset->dead_ring),
+                                     ep, pfd_elem_t, link);
+                break;
+            }
+        }
+    }
+
+    pollset_unlock_rings();
+
+    return rv;
+}
+
+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)
+{
+    int ret, i;
+    pfd_elem_t *ep;
+    struct timespec tv, *tvptr;
+    apr_status_t rv = APR_SUCCESS;
+
+    if (timeout < 0) {
+        tvptr = NULL;
+    }
+    else {
+        tv.tv_sec = (long) apr_time_sec(timeout);
+        tv.tv_nsec = (long) apr_time_msec(timeout);
+        tvptr = &tv;
+    }
+
+    ret = kevent(pollset->kqueue_fd, NULL, 0, pollset->ke_set, pollset->nalloc,
+                tvptr);
+    (*num) = ret;
+    if (ret < 0) {
+        rv = apr_get_netos_error();
+    }
+    else if (ret == 0) {
+        rv = APR_TIMEUP;
+    }
+    else {
+        for (i = 0; i < ret; i++) {
+            pollset->result_set[i] =
+                (((pfd_elem_t*)(pollset->ke_set[i].udata))->pfd);
+            pollset->result_set[i].rtnevents =
+                get_kqueue_revent(pollset->ke_set[i].filter,
+                              pollset->ke_set[i].flags);
+        }
+
+        if (descriptors) {
+            *descriptors = pollset->result_set;
+        }
+    }
+
+
+    pollset_lock_rings();
+
+    /* Shift all PFDs in the Dead Ring to be Free Ring */
+    while (!APR_RING_EMPTY(&(pollset->dead_ring), pfd_elem_t, link)) {
+        ep = APR_RING_FIRST(&(pollset->dead_ring));
+        APR_RING_REMOVE(ep, link);
+        APR_RING_INSERT_TAIL(&(pollset->free_ring), ep, pfd_elem_t, link);
+    }
+
+    pollset_unlock_rings();
+
+    return rv;
+}
+
+#endif /* POLLSET_USES_KQUEUE */

Modified: apr/apr/trunk/poll/unix/poll.c
==============================================================================
--- apr/apr/trunk/poll/unix/poll.c	(original)
+++ apr/apr/trunk/poll/unix/poll.c	Fri Nov 19 16:28:19 2004
@@ -13,94 +13,9 @@
  * limitations under the License.
  */
 
-#include "apr.h"
-#include "apr_poll.h"
-#include "apr_time.h"
-#include "apr_portable.h"
-#include "apr_arch_networkio.h"
-#include "apr_arch_file_io.h"
-#if HAVE_POLL_H
-#include <poll.h>
-#endif
-#if HAVE_SYS_POLL_H
-#include <sys/poll.h>
-#endif
-
-#ifdef HAVE_KQUEUE
-#include <sys/types.h>
-#include <sys/event.h>
-#include <sys/time.h>
-#endif
-
-#ifdef HAVE_EPOLL
-#include <sys/epoll.h>
-#endif
-
-#ifdef NETWARE
-#define HAS_SOCKETS(dt) (dt == APR_POLL_SOCKET) ? 1 : 0
-#define HAS_PIPES(dt) (dt == APR_POLL_FILE) ? 1 : 0
-#endif
-
-#ifdef HAVE_KQUEUE
-static apr_int16_t get_kqueue_revent(apr_int16_t event, apr_int16_t flags)
-{
-    apr_int16_t rv = 0;
-
-    if (event & EVFILT_READ)
-        rv |= APR_POLLIN;
-    if (event & EVFILT_WRITE)
-        rv |= APR_POLLOUT;
-    if (flags & EV_EOF)
-        rv |= APR_POLLHUP;
-    if (flags & EV_ERROR)
-        rv |= APR_POLLERR;
-
-    return rv;
-}
-
-#endif
+#include "apr_arch_poll_private.h"
 
-#ifdef HAVE_EPOLL
-static apr_int16_t get_epoll_event(apr_int16_t event)
-{
-    apr_int16_t rv = 0;
-
-    if (event & APR_POLLIN)
-        rv |= EPOLLIN;
-    if (event & APR_POLLPRI)
-        rv |= EPOLLPRI;
-    if (event & APR_POLLOUT)
-        rv |= EPOLLOUT;
-    if (event & APR_POLLERR)
-        rv |= EPOLLERR;
-    if (event & APR_POLLHUP)
-        rv |= EPOLLHUP;
-    /* APR_POLLNVAL is not handled by epoll. */
-
-    return rv;
-}
-
-static apr_int16_t get_epoll_revent(apr_int16_t event)
-{
-    apr_int16_t rv = 0;
-
-    if (event & EPOLLIN)
-        rv |= APR_POLLIN;
-    if (event & EPOLLPRI)
-        rv |= APR_POLLPRI;
-    if (event & EPOLLOUT)
-        rv |= APR_POLLOUT;
-    if (event & EPOLLERR)
-        rv |= APR_POLLERR;
-    if (event & EPOLLHUP)
-        rv |= APR_POLLHUP;
-    /* APR_POLLNVAL is not handled by epoll. */
-
-    return rv;
-}
-#endif
-
-#ifdef HAVE_POLL    /* We can just use poll to do our socket polling. */
+#if defined(POLL_USES_POLL) || defined(POLLSET_USES_POLL)
 
 static apr_int16_t get_event(apr_int16_t event)
 {
@@ -142,6 +57,11 @@
     return rv;
 }
 
+#endif /* POLL_USES_POLL || POLLSET_USES_POLL */
+
+
+#ifdef POLL_USES_POLL
+
 #define SMALL_POLLSET_LIMIT  8
 
 APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, apr_int32_t num,
@@ -216,298 +136,55 @@
 }
 
 
-#else    /* Use select to mimic poll */
-
-APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, int num, apr_int32_t *nsds, 
-		    apr_interval_time_t timeout)
-{
-    fd_set readset, writeset, exceptset;
-    int rv, i;
-    int maxfd = -1;
-    struct timeval tv, *tvptr;
-#ifdef NETWARE
-    apr_datatype_e set_type = APR_NO_DESC;
-#endif
-
-    if (timeout < 0) {
-        tvptr = NULL;
-    }
-    else {
-        tv.tv_sec = (long)apr_time_sec(timeout);
-        tv.tv_usec = (long)apr_time_usec(timeout);
-        tvptr = &tv;
-    }
-
-    FD_ZERO(&readset);
-    FD_ZERO(&writeset);
-    FD_ZERO(&exceptset);
-
-    for (i = 0; i < num; i++) {
-        apr_os_sock_t fd;
-
-        aprset[i].rtnevents = 0;
-
-        if (aprset[i].desc_type == APR_POLL_SOCKET) {
-#ifdef NETWARE
-            if (HAS_PIPES(set_type)) {
-                return APR_EBADF;
-            }
-            else {
-                set_type = APR_POLL_SOCKET;
-            }
-#endif
-            fd = aprset[i].desc.s->socketdes;
-        }
-        else if (aprset[i].desc_type == APR_POLL_FILE) {
-#if !APR_FILES_AS_SOCKETS
-            return APR_EBADF;
-#else
-#ifdef NETWARE
-            if (aprset[i].desc.f->is_pipe && !HAS_SOCKETS(set_type)) {
-                set_type = APR_POLL_FILE;
-            }
-            else
-                return APR_EBADF;
-#endif /* NETWARE */
-
-            fd = aprset[i].desc.f->filedes;
-
-#endif /* APR_FILES_AS_SOCKETS */
-        }
-        else {
-            break;
-        }
-#if !defined(WIN32) && !defined(NETWARE) /* socket sets handled with array of handles */
-        if (fd >= FD_SETSIZE) {
-            /* XXX invent new error code so application has a clue */
-            return APR_EBADF;
-        }
-#endif
-        if (aprset[i].reqevents & APR_POLLIN) {
-            FD_SET(fd, &readset);
-        }
-        if (aprset[i].reqevents & APR_POLLOUT) {
-            FD_SET(fd, &writeset);
-        }
-        if (aprset[i].reqevents & 
-            (APR_POLLPRI | APR_POLLERR | APR_POLLHUP | APR_POLLNVAL)) {
-            FD_SET(fd, &exceptset);
-        }
-        if ((int)fd > maxfd) {
-            maxfd = (int)fd;
-        }
-    }
+#endif /* POLL_USES_POLL */
 
-#ifdef NETWARE
-    if (HAS_PIPES(set_type)) {
-        rv = pipe_select(maxfd + 1, &readset, &writeset, &exceptset, tvptr);
-    }
-    else {
-#endif
 
-    rv = select(maxfd + 1, &readset, &writeset, &exceptset, tvptr);
-
-#ifdef NETWARE
-    }
-#endif
+#ifdef POLLSET_USES_POLL
 
-    (*nsds) = rv;
-    if ((*nsds) == 0) {
-        return APR_TIMEUP;
-    }
-    if ((*nsds) < 0) {
-        return apr_get_netos_error();
-    }
-
-    for (i = 0; i < num; i++) {
-        apr_os_sock_t fd;
-
-        if (aprset[i].desc_type == APR_POLL_SOCKET) {
-            fd = aprset[i].desc.s->socketdes;
-        }
-        else if (aprset[i].desc_type == APR_POLL_FILE) {
-#if !APR_FILES_AS_SOCKETS
-            return APR_EBADF;
-#else
-            fd = aprset[i].desc.f->filedes;
-#endif
-        }
-        else {
-            break;
-        }
-        if (FD_ISSET(fd, &readset)) {
-            aprset[i].rtnevents |= APR_POLLIN;
-        }
-        if (FD_ISSET(fd, &writeset)) {
-            aprset[i].rtnevents |= APR_POLLOUT;
-        }
-        if (FD_ISSET(fd, &exceptset)) {
-            aprset[i].rtnevents |= APR_POLLERR;
-        }
-    }
-
-    return APR_SUCCESS;
-}
-
-#endif 
-
-struct apr_pollset_t {
+struct apr_pollset_t
+{
     apr_pool_t *pool;
-
     apr_uint32_t nelts;
     apr_uint32_t nalloc;
-#ifdef HAVE_KQUEUE
-    int kqueue_fd;
-    struct kevent kevent;
-    struct kevent *ke_set;
-#elif defined(HAVE_EPOLL)
-    int epoll_fd;
-    struct epoll_event *pollset;
-#elif defined(HAVE_POLL)
     struct pollfd *pollset;
-#else
-    fd_set readset, writeset, exceptset;
-    int maxfd;
-#endif
     apr_pollfd_t *query_set;
     apr_pollfd_t *result_set;
-
-#ifdef NETWARE
-    int set_type;
-#endif
 };
 
-#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
-static apr_status_t backend_cleanup(void *p_)
-{
-    apr_pollset_t *pollset = (apr_pollset_t *)p_;
-#ifdef HAVE_KQUEUE
-    close(pollset->kqueue_fd);
-#elif defined(HAVE_EPOLL)
-    close(pollset->epoll_fd);
-#endif
-    return APR_SUCCESS;
-}
-#endif /* HAVE_KQUEUE || HAVE_EPOLL */
-
 APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
                                              apr_uint32_t size,
                                              apr_pool_t *p,
                                              apr_uint32_t flags)
 {
-#if !defined(HAVE_KQUEUE) && !defined(HAVE_EPOLL) && !defined(HAVE_POLL) && defined(FD_SETSIZE)
-    if (size > FD_SETSIZE) {
+    if (flags & APR_POLLSET_THREADSAFE) {                
         *pollset = NULL;
-        return APR_EINVAL;
+        return APR_ENOTIMPL;
     }
-#endif
+
     *pollset = apr_palloc(p, sizeof(**pollset));
     (*pollset)->nelts = 0;
     (*pollset)->nalloc = size;
     (*pollset)->pool = p;
-#ifdef HAVE_KQUEUE
-    (*pollset)->ke_set = (struct kevent*)apr_palloc(p, size * sizeof(struct  kevent));
-    memset((*pollset)->ke_set, 0, size * sizeof(struct kevent));
-    (*pollset)->kqueue_fd = kqueue();
-    if ((*pollset)->kqueue_fd == -1) {
-         return APR_ENOMEM;
-    }
-    apr_pool_cleanup_register(p, (void*)(*pollset), backend_cleanup, 
-        apr_pool_cleanup_null);
-#elif defined(HAVE_EPOLL)
-    (*pollset)->epoll_fd = epoll_create(size);
-    (*pollset)->pollset = apr_palloc(p, size * sizeof(struct epoll_event));
-    apr_pool_cleanup_register(p, (void*)(*pollset), backend_cleanup, 
-        apr_pool_cleanup_null);
-#elif defined(HAVE_POLL)
     (*pollset)->pollset = apr_palloc(p, size * sizeof(struct pollfd));
-#else
-    FD_ZERO(&((*pollset)->readset));
-    FD_ZERO(&((*pollset)->writeset));
-    FD_ZERO(&((*pollset)->exceptset));
-    (*pollset)->maxfd = 0;
-#ifdef NETWARE
-    (*pollset)->set_type = APR_NO_DESC;
-#endif
-#endif
     (*pollset)->query_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
     (*pollset)->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
-
     return APR_SUCCESS;
 }
 
 APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset)
 {
-#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL)
-    return apr_pool_cleanup_run(pollset->pool, pollset, backend_cleanup);
-#else
     return APR_SUCCESS;
-#endif
 }
 
 APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset,
                                           const apr_pollfd_t *descriptor)
 {
-#ifdef HAVE_KQUEUE
-    apr_os_sock_t fd;
-#elif defined(HAVE_EPOLL)
-    struct epoll_event ev;
-    int ret = -1;
-#else
-#if !defined(HAVE_POLL)
-    apr_os_sock_t fd;
-#endif
-#endif
-
     if (pollset->nelts == pollset->nalloc) {
         return APR_ENOMEM;
     }
 
     pollset->query_set[pollset->nelts] = *descriptor;
 
-#ifdef HAVE_KQUEUE
-    if (descriptor->desc_type == APR_POLL_SOCKET) {
-        fd = descriptor->desc.s->socketdes;
-    }
-    else {
-        fd = descriptor->desc.f->filedes;
-    }
-
-    if (descriptor->reqevents & APR_POLLIN) {
-        EV_SET(&pollset->kevent, fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
-
-        if (kevent(pollset->kqueue_fd, &pollset->kevent, 1, NULL, 0,
-                   NULL) == -1) {
-            return APR_ENOMEM;
-        }
-    }
-
-    if (descriptor->reqevents & APR_POLLOUT) {
-        EV_SET(&pollset->kevent, fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL);
-
-        if (kevent(pollset->kqueue_fd, &pollset->kevent, 1, NULL, 0,
-                   NULL) == -1) {
-            return APR_ENOMEM;
-        }
-    }
-
-#elif defined(HAVE_EPOLL)
-    ev.events = get_epoll_event(descriptor->reqevents);
-    if (descriptor->desc_type == APR_POLL_SOCKET) {
-        ev.data.fd = descriptor->desc.s->socketdes;
-        ret = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_ADD,
-                        descriptor->desc.s->socketdes, &ev);
-    }
-    else {
-        ev.data.fd = descriptor->desc.f->filedes;
-        ret = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_ADD,
-                        descriptor->desc.f->filedes, &ev);
-    }
-    if (0 != ret) {
-        return APR_EBADF;
-    }
-#elif defined(HAVE_POLL)
-
     if (descriptor->desc_type == APR_POLL_SOCKET) {
         pollset->pollset[pollset->nelts].fd = descriptor->desc.s->socketdes;
     }
@@ -515,59 +192,10 @@
         pollset->pollset[pollset->nelts].fd = descriptor->desc.f->filedes;
     }
 
-    pollset->pollset[pollset->nelts].events = get_event(descriptor->reqevents);
-#else
-    if (descriptor->desc_type == APR_POLL_SOCKET) {
-#ifdef NETWARE
-        /* NetWare can't handle mixed descriptor types in select() */
-        if (HAS_PIPES(pollset->set_type)) {
-            return APR_EBADF;
-        }
-        else {
-            pollset->set_type = APR_POLL_SOCKET;
-        }
-#endif
-        fd = descriptor->desc.s->socketdes;
-    }
-    else {
-#if !APR_FILES_AS_SOCKETS
-        return APR_EBADF;
-#else
-#ifdef NETWARE
-        /* NetWare can't handle mixed descriptor types in select() */
-        if (descriptor->desc.f->is_pipe && !HAS_SOCKETS(pollset->set_type)) {
-            pollset->set_type = APR_POLL_FILE;
-            fd = descriptor->desc.f->filedes;
-        }
-        else {
-            return APR_EBADF;
-        }
-#else
-        fd = descriptor->desc.f->filedes;
-#endif
-#endif
-    }
-#if !defined(WIN32) && !defined(NETWARE) /* socket sets handled with array of handles */
-    if (fd >= FD_SETSIZE) {
-        /* XXX invent new error code so application has a clue */
-        return APR_EBADF;
-    }
-#endif
-    if (descriptor->reqevents & APR_POLLIN) {
-        FD_SET(fd, &(pollset->readset));
-    }
-    if (descriptor->reqevents & APR_POLLOUT) {
-        FD_SET(fd, &(pollset->writeset));
-    }
-    if (descriptor->reqevents &
-        (APR_POLLPRI | APR_POLLERR | APR_POLLHUP | APR_POLLNVAL)) {
-        FD_SET(fd, &(pollset->exceptset));
-    }
-    if ((int)fd > pollset->maxfd) {
-        pollset->maxfd = (int)fd;
-    }
-#endif
+    pollset->pollset[pollset->nelts].events =
+        get_event(descriptor->reqevents);
     pollset->nelts++;
+
     return APR_SUCCESS;
 }
 
@@ -575,97 +203,8 @@
                                              const apr_pollfd_t *descriptor)
 {
     apr_uint32_t i;
-#ifdef HAVE_KQUEUE
     apr_os_sock_t fd;
-#elif defined(HAVE_EPOLL)
-    struct epoll_event ev;
-    int ret = -1;
-#elif !defined(HAVE_POLL)
-    apr_os_sock_t fd;
-#endif
-
-#ifdef HAVE_KQUEUE
-    for (i = 0; i < pollset->nelts; i++) {
-        if (descriptor->desc.s == pollset->query_set[i].desc.s) {
-            /* Found an instance of the fd: remove this and any other copies  */
-            apr_uint32_t dst = i;
-            apr_uint32_t old_nelts = pollset->nelts;
-            pollset->nelts--;
-            for (i++; i < old_nelts; i++) {
-                if (descriptor->desc.s == pollset->query_set[i].desc.s) {
-                    pollset->nelts--;
-                }
-                else {
-                    pollset->query_set[dst] = pollset->query_set[i];
-                    dst++;
-                }
-            }
-
-            if (descriptor->desc_type == APR_POLL_SOCKET) {
-                fd = descriptor->desc.s->socketdes;
-            }
-            else {
-                fd = descriptor->desc.f->filedes;
-            }
-
-            if (descriptor->reqevents & APR_POLLIN) {
-                EV_SET(&pollset->kevent, fd,
-                       EVFILT_READ, EV_DELETE, 0, 0, NULL);
-
-                if (kevent(pollset->kqueue_fd, &pollset->kevent, 1, NULL, 0,
-                          NULL) == -1) {
-                    return APR_EBADF;
-                }
-            }
-
-            if (descriptor->reqevents & APR_POLLOUT) {
-                EV_SET(&pollset->kevent, fd,
-                       EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
-
-                if (kevent(pollset->kqueue_fd, &pollset->kevent, 1, NULL, 0,
-                          NULL) == -1) {
-                    return APR_EBADF;
-                }
-            }
-
-            return APR_SUCCESS;
-        }
-    }
-#elif defined(HAVE_EPOLL)
-    for (i = 0; i < pollset->nelts; i++) {
-        if (descriptor->desc.s == pollset->query_set[i].desc.s) {
-            /* Found an instance of the fd: remove this and any other copies  */
-            apr_uint32_t dst = i;
-            apr_uint32_t old_nelts = pollset->nelts;
-            pollset->nelts--;
-            for (i++; i < old_nelts; i++) {
-                if (descriptor->desc.s == pollset->query_set[i].desc.s) {
-                    pollset->nelts--;
-                }
-                else {
-                    pollset->query_set[dst] = pollset->query_set[i];
-                    dst++;
-                }
-            }
-            ev.events = get_epoll_event(descriptor->reqevents);
-            if (descriptor->desc_type == APR_POLL_SOCKET) {
-                ev.data.fd = descriptor->desc.s->socketdes;
-                ret = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_DEL,
-                                descriptor->desc.s->socketdes, &ev);
-            }
-            else {
-                ev.data.fd = descriptor->desc.f->filedes;
-                ret = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_DEL,
-                                descriptor->desc.f->filedes, &ev);
-            }
-            if (ret < 0) {
-                return APR_EBADF;
-            }
 
-            return APR_SUCCESS;
-        }
-    }
-#elif defined(HAVE_POLL)
     for (i = 0; i < pollset->nelts; i++) {
         if (descriptor->desc.s == pollset->query_set[i].desc.s) {
             /* Found an instance of the fd: remove this and any other copies */
@@ -686,159 +225,9 @@
         }
     }
 
-#else /* no poll */
-    if (descriptor->desc_type == APR_POLL_SOCKET) {
-        fd = descriptor->desc.s->socketdes;
-    }
-    else {
-#if !APR_FILES_AS_SOCKETS
-        return APR_EBADF;
-#else
-        fd = descriptor->desc.f->filedes;
-#endif
-    }
-
-    for (i = 0; i < pollset->nelts; i++) {
-        if (descriptor->desc.s == pollset->query_set[i].desc.s) {
-            /* Found an instance of the fd: remove this and any other copies */
-            apr_uint32_t dst = i;
-            apr_uint32_t old_nelts = pollset->nelts;
-            pollset->nelts--;
-            for (i++; i < old_nelts; i++) {
-                if (descriptor->desc.s == pollset->query_set[i].desc.s) {
-                    pollset->nelts--;
-                }
-                else {
-                    pollset->query_set[dst] = pollset->query_set[i];
-                    dst++;
-                }
-            }
-            FD_CLR(fd, &(pollset->readset));
-            FD_CLR(fd, &(pollset->writeset));
-            FD_CLR(fd, &(pollset->exceptset));
-            if (((int)fd == pollset->maxfd) && (pollset->maxfd > 0)) {
-                pollset->maxfd--;
-            }
-            return APR_SUCCESS;
-        }
-    }
-#endif /* no poll */
-
     return APR_NOTFOUND;
 }
-#ifdef HAVE_KQUEUE
-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)
-{
-    int rv;
-    apr_uint32_t i, j, r = 0;
-    struct timespec tv, *tvptr;
-
-    if (timeout < 0) {
-        tvptr = NULL;
-    }
-    else {
-        tv.tv_sec = (long)apr_time_sec(timeout);
-        tv.tv_nsec = (long)apr_time_msec(timeout);
-        tvptr = &tv;
-    }
-
-    rv = kevent(pollset->kqueue_fd, NULL, 0, pollset->ke_set, pollset->nelts,
-                tvptr);
-    (*num) = rv;
-    if (rv < 0) {
-        return apr_get_netos_error();
-    }
-    if (rv == 0) {
-        return APR_TIMEUP;
-    }
-
-    /* TODO: Is there a better way to re-associate our data? */
-    for (i = 0; i < pollset->nelts; i++) {
-        apr_os_sock_t fd;
-        if (pollset->query_set[i].desc_type == APR_POLL_SOCKET) {
-            fd = pollset->query_set[i].desc.s->socketdes;
-        }
-        else {
-            fd = pollset->query_set[i].desc.f->filedes;
-        }
-        for (j = 0; j < rv; j++) {
-            if (pollset->ke_set[j].ident == fd ) {
-                pollset->result_set[r] = pollset->query_set[i];
-                pollset->result_set[r].rtnevents =
-                    get_kqueue_revent(pollset->ke_set[j].filter,
-                                      pollset->ke_set[j].flags);
-                r++;
-            }
-        }
-    }
-
-    (*num) = r;
-
-    if (descriptors) {
-        *descriptors = pollset->result_set;
-    }
-
-    return APR_SUCCESS;
-}
-
-#elif defined(HAVE_EPOLL)
-
-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)
-{
-    int rv;
-    apr_uint32_t i, j, k;
-
-    if (timeout > 0) {
-        timeout /= 1000;
-    }
 
-    rv = epoll_wait(pollset->epoll_fd, pollset->pollset, pollset->nelts,
-                    timeout);
-    (*num) = rv;
-    if (rv < 0) {
-        return apr_get_netos_error();
-    }
-    if (rv == 0) {
-        return APR_TIMEUP;
-    }
-    j = 0;
-    for (i = 0; i < pollset->nelts; i++) {
-        if (pollset->pollset[i].events != 0) {
-            /* TODO: Is there a better way to re-associate our data? */
-            for (k = 0; k < pollset->nelts; k++) {
-                if (pollset->query_set[k].desc_type == APR_POLL_SOCKET &&
-                    pollset->query_set[k].desc.s->socketdes ==
-                        pollset->pollset[i].data.fd) {
-                    pollset->result_set[j] = pollset->query_set[k];
-                    pollset->result_set[j].rtnevents =
-                        get_epoll_revent(pollset->pollset[i].events);
-                    j++;
-                    break;
-                }
-                else if (pollset->query_set[k].desc_type == APR_POLL_FILE 
-                         && pollset->query_set[k].desc.f->filedes ==
-                            pollset->pollset[i].data.fd) {
-                    pollset->result_set[j] = pollset->query_set[k];
-                    pollset->result_set[j].rtnevents =
-                        get_epoll_revent(pollset->pollset[i].events);
-                    j++;
-                    break;
-                }
-            }
-        }
-    }
-    if (descriptors) {
-        *descriptors = pollset->result_set;
-    }
-    return APR_SUCCESS;
-}
-#elif defined(HAVE_POLL)
 APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset,
                                            apr_interval_time_t timeout,
                                            apr_int32_t *num,
@@ -872,79 +261,4 @@
     return APR_SUCCESS;
 }
 
-#else /* no poll */
-
-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)
-{
-    int rv;
-    apr_uint32_t i, j;
-    struct timeval tv, *tvptr;
-    fd_set readset, writeset, exceptset;
-
-    if (timeout < 0) {
-        tvptr = NULL;
-    }
-    else {
-        tv.tv_sec = (long)apr_time_sec(timeout);
-        tv.tv_usec = (long)apr_time_usec(timeout);
-        tvptr = &tv;
-    }
-
-    memcpy(&readset, &(pollset->readset), sizeof(fd_set));
-    memcpy(&writeset, &(pollset->writeset), sizeof(fd_set));
-    memcpy(&exceptset, &(pollset->exceptset), sizeof(fd_set));
-
-#ifdef NETWARE
-    if (HAS_PIPES(pollset->set_type)) {
-        rv = pipe_select(pollset->maxfd + 1, &readset, &writeset, &exceptset, tvptr);
-    }
-    else
-#endif
-    rv = select(pollset->maxfd + 1, &readset, &writeset, &exceptset, tvptr);
-
-    (*num) = rv;
-    if (rv < 0) {
-        return apr_get_netos_error();
-    }
-    if (rv == 0) {
-        return APR_TIMEUP;
-    }
-    j = 0;
-    for (i = 0; i < pollset->nelts; i++) {
-        apr_os_sock_t fd;
-        if (pollset->query_set[i].desc_type == APR_POLL_SOCKET) {
-            fd = pollset->query_set[i].desc.s->socketdes;
-        }
-        else {
-#if !APR_FILES_AS_SOCKETS
-            return APR_EBADF;
-#else
-            fd = pollset->query_set[i].desc.f->filedes;
-#endif
-        }
-        if (FD_ISSET(fd, &readset) || FD_ISSET(fd, &writeset) ||
-            FD_ISSET(fd, &exceptset)) {
-            pollset->result_set[j] = pollset->query_set[i];
-            pollset->result_set[j].rtnevents = 0;
-            if (FD_ISSET(fd, &readset)) {
-                pollset->result_set[j].rtnevents |= APR_POLLIN;
-            }
-            if (FD_ISSET(fd, &writeset)) {
-                pollset->result_set[j].rtnevents |= APR_POLLOUT;
-            }
-            if (FD_ISSET(fd, &exceptset)) {
-                pollset->result_set[j].rtnevents |= APR_POLLERR;
-            }
-            j++;
-        }
-    }
-
-    if (descriptors)
-        *descriptors = pollset->result_set;
-    return APR_SUCCESS;
-}
-
-#endif /* no poll */
+#endif /* POLLSET_USES_POLL */

Added: apr/apr/trunk/poll/unix/select.c
==============================================================================
--- (empty file)
+++ apr/apr/trunk/poll/unix/select.c	Fri Nov 19 16:28:19 2004
@@ -0,0 +1,392 @@
+/* Copyright 2000-2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+#include "apr_arch_poll_private.h"
+
+#ifdef POLL_USES_SELECT
+
+APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, int num,
+                                   apr_int32_t *nsds,
+                                   apr_interval_time_t timeout)
+{
+    fd_set readset, writeset, exceptset;
+    int rv, i;
+    int maxfd = -1;
+    struct timeval tv, *tvptr;
+#ifdef NETWARE
+    apr_datatype_e set_type = APR_NO_DESC;
+#endif
+
+    if (timeout < 0) {
+        tvptr = NULL;
+    }
+    else {
+        tv.tv_sec = (long) apr_time_sec(timeout);
+        tv.tv_usec = (long) apr_time_usec(timeout);
+        tvptr = &tv;
+    }
+
+    FD_ZERO(&readset);
+    FD_ZERO(&writeset);
+    FD_ZERO(&exceptset);
+
+    for (i = 0; i < num; i++) {
+        apr_os_sock_t fd;
+
+        aprset[i].rtnevents = 0;
+
+        if (aprset[i].desc_type == APR_POLL_SOCKET) {
+#ifdef NETWARE
+            if (HAS_PIPES(set_type)) {
+                return APR_EBADF;
+            }
+            else {
+                set_type = APR_POLL_SOCKET;
+            }
+#endif
+            fd = aprset[i].desc.s->socketdes;
+        }
+        else if (aprset[i].desc_type == APR_POLL_FILE) {
+#if !APR_FILES_AS_SOCKETS
+            return APR_EBADF;
+#else
+#ifdef NETWARE
+            if (aprset[i].desc.f->is_pipe && !HAS_SOCKETS(set_type)) {
+                set_type = APR_POLL_FILE;
+            }
+            else
+                return APR_EBADF;
+#endif /* NETWARE */
+
+            fd = aprset[i].desc.f->filedes;
+
+#endif /* APR_FILES_AS_SOCKETS */
+        }
+        else {
+            break;
+        }
+#if !defined(WIN32) && !defined(NETWARE)        /* socket sets handled with array of handles */
+        if (fd >= FD_SETSIZE) {
+            /* XXX invent new error code so application has a clue */
+            return APR_EBADF;
+        }
+#endif
+        if (aprset[i].reqevents & APR_POLLIN) {
+            FD_SET(fd, &readset);
+        }
+        if (aprset[i].reqevents & APR_POLLOUT) {
+            FD_SET(fd, &writeset);
+        }
+        if (aprset[i].reqevents &
+            (APR_POLLPRI | APR_POLLERR | APR_POLLHUP | APR_POLLNVAL)) {
+            FD_SET(fd, &exceptset);
+        }
+        if ((int) fd > maxfd) {
+            maxfd = (int) fd;
+        }
+    }
+
+#ifdef NETWARE
+    if (HAS_PIPES(set_type)) {
+        rv = pipe_select(maxfd + 1, &readset, &writeset, &exceptset, tvptr);
+    }
+    else {
+#endif
+
+        rv = select(maxfd + 1, &readset, &writeset, &exceptset, tvptr);
+
+#ifdef NETWARE
+    }
+#endif
+
+    (*nsds) = rv;
+    if ((*nsds) == 0) {
+        return APR_TIMEUP;
+    }
+    if ((*nsds) < 0) {
+        return apr_get_netos_error();
+    }
+
+    for (i = 0; i < num; i++) {
+        apr_os_sock_t fd;
+
+        if (aprset[i].desc_type == APR_POLL_SOCKET) {
+            fd = aprset[i].desc.s->socketdes;
+        }
+        else if (aprset[i].desc_type == APR_POLL_FILE) {
+#if !APR_FILES_AS_SOCKETS
+            return APR_EBADF;
+#else
+            fd = aprset[i].desc.f->filedes;
+#endif
+        }
+        else {
+            break;
+        }
+        if (FD_ISSET(fd, &readset)) {
+            aprset[i].rtnevents |= APR_POLLIN;
+        }
+        if (FD_ISSET(fd, &writeset)) {
+            aprset[i].rtnevents |= APR_POLLOUT;
+        }
+        if (FD_ISSET(fd, &exceptset)) {
+            aprset[i].rtnevents |= APR_POLLERR;
+        }
+    }
+
+    return APR_SUCCESS;
+}
+
+#endif /* POLL_USES_SELECT */
+
+#ifdef POLLSET_USES_SELECT
+
+struct apr_pollset_t
+{
+    apr_pool_t *pool;
+
+    apr_uint32_t nelts;
+    apr_uint32_t nalloc;
+    fd_set readset, writeset, exceptset;
+    int maxfd;
+    apr_pollfd_t *query_set;
+    apr_pollfd_t *result_set;
+#ifdef NETWARE
+    int set_type;
+#endif
+};
+
+APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
+                                             apr_uint32_t size,
+                                             apr_pool_t *p,
+                                             apr_uint32_t flags)
+{
+    if (flags & APR_POLLSET_THREADSAFE) {                
+        *pollset = NULL;
+        return APR_ENOTIMPL;
+    }
+#ifdef FD_SETSIZE
+    if (size > FD_SETSIZE) {
+        *pollset = NULL;
+        return APR_EINVAL;
+    }
+#endif
+    *pollset = apr_palloc(p, sizeof(**pollset));
+    (*pollset)->nelts = 0;
+    (*pollset)->nalloc = size;
+    (*pollset)->pool = p;
+    FD_ZERO(&((*pollset)->readset));
+    FD_ZERO(&((*pollset)->writeset));
+    FD_ZERO(&((*pollset)->exceptset));
+    (*pollset)->maxfd = 0;
+#ifdef NETWARE
+    (*pollset)->set_type = APR_NO_DESC;
+#endif
+    (*pollset)->query_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
+    (*pollset)->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
+
+    return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t * pollset)
+{
+    return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset,
+                                          const apr_pollfd_t *descriptor)
+{
+    apr_os_sock_t fd;
+
+    if (pollset->nelts == pollset->nalloc) {
+        return APR_ENOMEM;
+    }
+
+    pollset->query_set[pollset->nelts] = *descriptor;
+
+    if (descriptor->desc_type == APR_POLL_SOCKET) {
+#ifdef NETWARE
+        /* NetWare can't handle mixed descriptor types in select() */
+        if (HAS_PIPES(pollset->set_type)) {
+            return APR_EBADF;
+        }
+        else {
+            pollset->set_type = APR_POLL_SOCKET;
+        }
+#endif
+        fd = descriptor->desc.s->socketdes;
+    }
+    else {
+#if !APR_FILES_AS_SOCKETS
+        return APR_EBADF;
+#else
+#ifdef NETWARE
+        /* NetWare can't handle mixed descriptor types in select() */
+        if (descriptor->desc.f->is_pipe && !HAS_SOCKETS(pollset->set_type)) {
+            pollset->set_type = APR_POLL_FILE;
+            fd = descriptor->desc.f->filedes;
+        }
+        else {
+            return APR_EBADF;
+        }
+#else
+        fd = descriptor->desc.f->filedes;
+#endif
+#endif
+    }
+#if !defined(WIN32) && !defined(NETWARE)        /* socket sets handled with array of handles */
+    if (fd >= FD_SETSIZE) {
+        /* XXX invent new error code so application has a clue */
+        return APR_EBADF;
+    }
+#endif
+    if (descriptor->reqevents & APR_POLLIN) {
+        FD_SET(fd, &(pollset->readset));
+    }
+    if (descriptor->reqevents & APR_POLLOUT) {
+        FD_SET(fd, &(pollset->writeset));
+    }
+    if (descriptor->reqevents &
+        (APR_POLLPRI | APR_POLLERR | APR_POLLHUP | APR_POLLNVAL)) {
+        FD_SET(fd, &(pollset->exceptset));
+    }
+    if ((int) fd > pollset->maxfd) {
+        pollset->maxfd = (int) fd;
+    }
+    pollset->nelts++;
+    return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t * pollset,
+                                             const apr_pollfd_t * descriptor)
+{
+    apr_uint32_t i;
+    apr_os_sock_t fd;
+
+    if (descriptor->desc_type == APR_POLL_SOCKET) {
+        fd = descriptor->desc.s->socketdes;
+    }
+    else {
+#if !APR_FILES_AS_SOCKETS
+        return APR_EBADF;
+#else
+        fd = descriptor->desc.f->filedes;
+#endif
+    }
+
+    for (i = 0; i < pollset->nelts; i++) {
+        if (descriptor->desc.s == pollset->query_set[i].desc.s) {
+            /* Found an instance of the fd: remove this and any other copies */
+            apr_uint32_t dst = i;
+            apr_uint32_t old_nelts = pollset->nelts;
+            pollset->nelts--;
+            for (i++; i < old_nelts; i++) {
+                if (descriptor->desc.s == pollset->query_set[i].desc.s) {
+                    pollset->nelts--;
+                }
+                else {
+                    pollset->query_set[dst] = pollset->query_set[i];
+                    dst++;
+                }
+            }
+            FD_CLR(fd, &(pollset->readset));
+            FD_CLR(fd, &(pollset->writeset));
+            FD_CLR(fd, &(pollset->exceptset));
+            if (((int) fd == pollset->maxfd) && (pollset->maxfd > 0)) {
+                pollset->maxfd--;
+            }
+            return APR_SUCCESS;
+        }
+    }
+
+    return APR_NOTFOUND;
+}
+
+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)
+{
+    int rv;
+    apr_uint32_t i, j;
+    struct timeval tv, *tvptr;
+    fd_set readset, writeset, exceptset;
+
+    if (timeout < 0) {
+        tvptr = NULL;
+    }
+    else {
+        tv.tv_sec = (long) apr_time_sec(timeout);
+        tv.tv_usec = (long) apr_time_usec(timeout);
+        tvptr = &tv;
+    }
+
+    memcpy(&readset, &(pollset->readset), sizeof(fd_set));
+    memcpy(&writeset, &(pollset->writeset), sizeof(fd_set));
+    memcpy(&exceptset, &(pollset->exceptset), sizeof(fd_set));
+
+#ifdef NETWARE
+    if (HAS_PIPES(pollset->set_type)) {
+        rv = pipe_select(pollset->maxfd + 1, &readset, &writeset, &exceptset,
+                         tvptr);
+    }
+    else
+#endif
+        rv = select(pollset->maxfd + 1, &readset, &writeset, &exceptset,
+                    tvptr);
+
+    (*num) = rv;
+    if (rv < 0) {
+        return apr_get_netos_error();
+    }
+    if (rv == 0) {
+        return APR_TIMEUP;
+    }
+    j = 0;
+    for (i = 0; i < pollset->nelts; i++) {
+        apr_os_sock_t fd;
+        if (pollset->query_set[i].desc_type == APR_POLL_SOCKET) {
+            fd = pollset->query_set[i].desc.s->socketdes;
+        }
+        else {
+#if !APR_FILES_AS_SOCKETS
+            return APR_EBADF;
+#else
+            fd = pollset->query_set[i].desc.f->filedes;
+#endif
+        }
+        if (FD_ISSET(fd, &readset) || FD_ISSET(fd, &writeset) ||
+            FD_ISSET(fd, &exceptset)) {
+            pollset->result_set[j] = pollset->query_set[i];
+            pollset->result_set[j].rtnevents = 0;
+            if (FD_ISSET(fd, &readset)) {
+                pollset->result_set[j].rtnevents |= APR_POLLIN;
+            }
+            if (FD_ISSET(fd, &writeset)) {
+                pollset->result_set[j].rtnevents |= APR_POLLOUT;
+            }
+            if (FD_ISSET(fd, &exceptset)) {
+                pollset->result_set[j].rtnevents |= APR_POLLERR;
+            }
+            j++;
+        }
+    }
+
+    if (descriptors)
+        *descriptors = pollset->result_set;
+    return APR_SUCCESS;
+}
+
+#endif /* POLLSET_USES_SELECT */

Mime
View raw message