You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by mt...@apache.org on 2009/02/13 13:24:01 UTC

svn commit: r744095 [1/2] - in /apr/apr/trunk: ./ include/ include/arch/unix/ poll/os2/ poll/unix/

Author: mturk
Date: Fri Feb 13 12:24:00 2009
New Revision: 744095

URL: http://svn.apache.org/viewvc?rev=744095&view=rev
Log:
Implement providers for apr_pollset and apr_pollcb

Modified:
    apr/apr/trunk/CHANGES
    apr/apr/trunk/NWGNUmakefile
    apr/apr/trunk/apr.dsp
    apr/apr/trunk/include/apr_poll.h
    apr/apr/trunk/include/arch/unix/apr_arch_poll_private.h
    apr/apr/trunk/libapr.dsp
    apr/apr/trunk/poll/os2/pollset.c
    apr/apr/trunk/poll/unix/epoll.c
    apr/apr/trunk/poll/unix/kqueue.c
    apr/apr/trunk/poll/unix/poll.c
    apr/apr/trunk/poll/unix/port.c
    apr/apr/trunk/poll/unix/select.c

Modified: apr/apr/trunk/CHANGES
URL: http://svn.apache.org/viewvc/apr/apr/trunk/CHANGES?rev=744095&r1=744094&r2=744095&view=diff
==============================================================================
--- apr/apr/trunk/CHANGES [utf-8] (original)
+++ apr/apr/trunk/CHANGES [utf-8] Fri Feb 13 12:24:00 2009
@@ -1,6 +1,11 @@
                                                      -*- coding: utf-8 -*-
 Changes for APR 2.0.0
 
+  *) Make apr_pollset and apr_pollcb implementations using providers.
+     Added apr_pollset_create_ex and apr_pollcb_create_ex that allows
+     choosing non-default providers.
+     [Mladen Turk]
+
   *) Intruduce APR_PERMS_SET macros for setting the owner/group on
      objects. Currently only implemented for shm, proc and global
      mutexes on posix platforms.

Modified: apr/apr/trunk/NWGNUmakefile
URL: http://svn.apache.org/viewvc/apr/apr/trunk/NWGNUmakefile?rev=744095&r1=744094&r2=744095&view=diff
==============================================================================
--- apr/apr/trunk/NWGNUmakefile (original)
+++ apr/apr/trunk/NWGNUmakefile Fri Feb 13 12:24:00 2009
@@ -311,6 +311,8 @@
 	$(OBJDIR)/rand.o \
 	$(OBJDIR)/readwrite.o \
 	$(OBJDIR)/seek.o \
+	$(OBJDIR)/pollcb.o \
+	$(OBJDIR)/pollset.o \
 	$(OBJDIR)/select.o \
 	$(OBJDIR)/sendrecv.o \
 	$(OBJDIR)/sha2.o \

Modified: apr/apr/trunk/apr.dsp
URL: http://svn.apache.org/viewvc/apr/apr/trunk/apr.dsp?rev=744095&r1=744094&r2=744095&view=diff
==============================================================================
--- apr/apr/trunk/apr.dsp (original)
+++ apr/apr/trunk/apr.dsp Fri Feb 13 12:24:00 2009
@@ -412,6 +412,14 @@
 # PROP Default_Filter ""
 # Begin Source File
 
+SOURCE=.\poll\unix\pollcb.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\poll\unix\pollset.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\poll\unix\select.c
 # End Source File
 # End Group

Modified: apr/apr/trunk/include/apr_poll.h
URL: http://svn.apache.org/viewvc/apr/apr/trunk/include/apr_poll.h?rev=744095&r1=744094&r2=744095&view=diff
==============================================================================
--- apr/apr/trunk/include/apr_poll.h (original)
+++ apr/apr/trunk/include/apr_poll.h Fri Feb 13 12:24:00 2009
@@ -57,6 +57,19 @@
 #define APR_POLLSET_THREADSAFE 0x001 /**< Adding or Removing a Descriptor is thread safe */
 #define APR_POLLSET_NOCOPY     0x002 /**< Descriptors passed to apr_pollset_create() are not copied */
 #define APR_POLLSET_WAKEABLE   0x004 /**< Pollset poll operation is interruptable */
+#define APR_POLLSET_NODEFAULT  0x010 /**< Do not try default method if non default fails */
+
+/**
+ * Pollset Methods
+ */
+typedef enum {
+    APR_POLLSET_DEFAULT,        /**< Platform default poll method */
+    APR_POLLSET_SELECT,         /**< Poll uses select method */
+    APR_POLLSET_KQUEUE,
+    APR_POLLSET_PORT,
+    APR_POLLSET_EPOLL,
+    APR_POLLSET_POLL
+} apr_pollset_method_e;
 
 /** Used in apr_pollfd_t to determine what the apr_descriptor is */
 typedef enum { 
@@ -119,6 +132,33 @@
                                              apr_uint32_t flags);
 
 /**
+ * Setup a pollset object
+ * @param pollset  The pointer in which to return the newly created object 
+ * @param size The maximum number of descriptors that this pollset can hold
+ * @param p The pool from which to allocate the pollset
+ * @param flags Optional flags to modify the operation of the pollset.
+ * @param method Poll method to use. See @apr_pollset_method_e.
+ *
+ * @remark If flags equals APR_POLLSET_THREADSAFE, then a pollset is
+ *         created on which it is safe to make concurrent calls to
+ *         apr_pollset_add(), apr_pollset_remove() and apr_pollset_poll()
+ *         from separate threads.  This feature is only supported on some
+ *         platforms; the apr_pollset_create() call will fail with
+ *         APR_ENOTIMPL on platforms where it is not supported.
+ * @remark If flags contain APR_POLLSET_WAKEABLE, then a pollset is
+ *         created with additional internal pipe object used for
+ *         apr_pollset_wakeup() call. The actual size of pollset is
+ *         in that case size + 1. This feature is only supported on some
+ *         platforms; the apr_pollset_create() call will fail with
+ *         APR_ENOTIMPL on platforms where it is not supported.
+ */
+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);
+
+/**
  * Destroy a pollset object
  * @param pollset The pollset to destroy
  */
@@ -207,6 +247,18 @@
                                    apr_int32_t *nsds, 
                                    apr_interval_time_t timeout);
 
+/**
+ * Display the name of the pollset method, as it relates to the actual
+ * method used.
+ * @param pollset the name of the pollset.
+ */
+APR_DECLARE(const char *) apr_pollset_method_name(apr_pollset_t *pollset);
+
+/**
+ * Display the name of the default poll method: APR_POLLSET_DEFAULT
+ */
+APR_DECLARE(const char *) apr_poll_method_defname(void);
+
 /** Opaque structure used for pollset API */
 typedef struct apr_pollcb_t apr_pollcb_t;
 
@@ -226,6 +278,23 @@
                                             apr_uint32_t flags);
 
 /**
+ * Setup a pollcb object
+ * @param pollcb  The pointer in which to return the newly created object 
+ * @param size The maximum number of descriptors that a single _poll can return.
+ * @param p The pool from which to allocate the pollcb
+ * @param flags Optional flags to modify the operation of the pollcb.
+ * @param method Poll method to use. See @apr_pollset_method_e.
+ *
+ * @remark Pollcb is only supported on some platforms; the apr_pollcb_create()
+ * call will fail with APR_ENOTIMPL on platforms where it is not supported.
+ */
+APR_DECLARE(apr_status_t) apr_pollcb_create_ex(apr_pollcb_t **pollcb,
+                                               apr_uint32_t size,
+                                               apr_pool_t *pool,
+                                               apr_uint32_t flags,
+                                               apr_pollset_method_e method);
+
+/**
  * Add a socket or file descriptor to a pollcb
  * @param pollcb The pollcb to which to add the descriptor
  * @param descriptor The descriptor to add

Modified: apr/apr/trunk/include/arch/unix/apr_arch_poll_private.h
URL: http://svn.apache.org/viewvc/apr/apr/trunk/include/arch/unix/apr_arch_poll_private.h?rev=744095&r1=744094&r2=744095&view=diff
==============================================================================
--- apr/apr/trunk/include/arch/unix/apr_arch_poll_private.h (original)
+++ apr/apr/trunk/include/arch/unix/apr_arch_poll_private.h Fri Feb 13 12:24:00 2009
@@ -17,13 +17,6 @@
 #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
@@ -55,14 +48,19 @@
 /* Choose the best method platform specific to use in apr_pollset */
 #ifdef HAVE_KQUEUE
 #define POLLSET_USES_KQUEUE
+#define POLLSET_DEFAULT_METHOD APR_POLLSET_KQUEUE
 #elif defined(HAVE_PORT_CREATE)
 #define POLLSET_USES_PORT
+#define POLLSET_DEFAULT_METHOD APR_POLLSET_PORT
 #elif defined(HAVE_EPOLL)
 #define POLLSET_USES_EPOLL
+#define POLLSET_DEFAULT_METHOD APR_POLLSET_EPOLL
 #elif defined(HAVE_POLL)
 #define POLLSET_USES_POLL
+#define POLLSET_DEFAULT_METHOD APR_POLLSET_POLL
 #else
 #define POLLSET_USES_SELECT
+#define POLLSET_DEFAULT_METHOD APR_POLLSET_SELECT
 #endif
 
 #ifdef HAVE_POLL
@@ -79,10 +77,10 @@
 #include "apr_thread_mutex.h"
 #define pollset_lock_rings() \
     if (pollset->flags & APR_POLLSET_THREADSAFE) \
-        apr_thread_mutex_lock(pollset->ring_lock);
+        apr_thread_mutex_lock(pollset->p->ring_lock);
 #define pollset_unlock_rings() \
     if (pollset->flags & APR_POLLSET_THREADSAFE) \
-        apr_thread_mutex_unlock(pollset->ring_lock);
+        apr_thread_mutex_unlock(pollset->p->ring_lock);
 #else
 #define pollset_lock_rings()
 #define pollset_unlock_rings()
@@ -97,4 +95,65 @@
 
 #endif
 
+typedef struct apr_pollset_private_t apr_pollset_private_t;
+typedef struct apr_pollset_provider_t apr_pollset_provider_t;
+typedef struct apr_pollcb_provider_t apr_pollcb_provider_t;
+struct apr_pollset_t
+{
+    apr_pool_t *pool;
+    apr_uint32_t nelts;
+    apr_uint32_t nalloc;
+    apr_uint32_t flags;
+    /* Pipe descriptors used for wakeup */
+    apr_file_t *wakeup_pipe[2];
+    apr_pollset_private_t *p;
+    apr_pollset_provider_t *provider;
+};
+
+typedef union {
+#if defined(HAVE_EPOLL)
+    struct epoll_event *epoll;
+#endif
+#if defined(HAVE_PORT_CREATE)
+    port_event_t *port;
+#endif
+#if defined(HAVE_KQUEUE)
+    struct kevent *ke;
+#endif
+#if defined(HAVE_POLL)
+    struct pollfd *ps;
+#endif
+    void *undef;
+} apr_pollcb_pset;
+
+struct apr_pollcb_t {
+    apr_pool_t *pool;
+    apr_uint32_t nelts;
+    apr_uint32_t nalloc;
+    int fd;
+    apr_pollcb_pset pollset;
+    apr_pollfd_t **copyset;
+    apr_pollcb_provider_t *provider;
+};
+
+struct apr_pollset_provider_t {
+    apr_status_t (*create)(apr_pollset_t *, apr_uint32_t, apr_pool_t *, apr_uint32_t);
+    apr_status_t (*add)(apr_pollset_t *, const apr_pollfd_t *);
+    apr_status_t (*remove)(apr_pollset_t *, const apr_pollfd_t *);
+    apr_status_t (*poll)(apr_pollset_t *, apr_interval_time_t, apr_int32_t *, const apr_pollfd_t **);
+    apr_status_t (*cleanup)(apr_pollset_t *);
+    const char *name;
+};
+
+struct apr_pollcb_provider_t {
+    apr_status_t (*create)(apr_pollcb_t *, apr_uint32_t, apr_pool_t *, apr_uint32_t);
+    apr_status_t (*add)(apr_pollcb_t *, apr_pollfd_t *);
+    apr_status_t (*remove)(apr_pollcb_t *, apr_pollfd_t *);
+    apr_status_t (*poll)(apr_pollcb_t *, apr_interval_time_t, apr_pollcb_cb_t, void *);
+    const char *name;
+};
+
+/* Private functions */
+void apr_pollset_drain_wakeup_pipe(apr_pollset_t *pollset);
+
 #endif /* APR_ARCH_POLL_PRIVATE_H */

Modified: apr/apr/trunk/libapr.dsp
URL: http://svn.apache.org/viewvc/apr/apr/trunk/libapr.dsp?rev=744095&r1=744094&r2=744095&view=diff
==============================================================================
--- apr/apr/trunk/libapr.dsp (original)
+++ apr/apr/trunk/libapr.dsp Fri Feb 13 12:24:00 2009
@@ -464,6 +464,14 @@
 # PROP Default_Filter ""
 # Begin Source File
 
+SOURCE=.\poll\unix\pollcb.c
+# End Source File
+# Begin Source File
+
+SOURCE=.\poll\unix\pollset.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\poll\unix\select.c
 # End Source File
 # End Group

Modified: apr/apr/trunk/poll/os2/pollset.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/poll/os2/pollset.c?rev=744095&r1=744094&r2=744095&view=diff
==============================================================================
--- apr/apr/trunk/poll/os2/pollset.c (original)
+++ apr/apr/trunk/poll/os2/pollset.c Fri Feb 13 12:24:00 2009
@@ -51,7 +51,14 @@
     return APR_SUCCESS;
 }
 
-
+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);
+{
+    return apr_pollset_create(pollset, size, p, flags);
+}
 
 APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset)
 {

Modified: apr/apr/trunk/poll/unix/epoll.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/poll/unix/epoll.c?rev=744095&r1=744094&r2=744095&view=diff
==============================================================================
--- apr/apr/trunk/poll/unix/epoll.c (original)
+++ apr/apr/trunk/poll/unix/epoll.c Fri Feb 13 12:24:00 2009
@@ -14,9 +14,15 @@
  * limitations under the License.
  */
 
+#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"
 
-#ifdef POLLSET_USES_EPOLL
+#if defined(HAVE_EPOLL)
 
 static apr_int16_t get_epoll_event(apr_int16_t event)
 {
@@ -56,17 +62,11 @@
     return rv;
 }
 
-struct apr_pollset_t
+struct apr_pollset_private_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;
-    /* Pipe descriptors used for wakeup */
-    apr_file_t *wakeup_pipe[2];
 #if APR_HAS_THREADS
     /* A thread mutex to protect operations on the rings */
     apr_thread_mutex_t *ring_lock;
@@ -80,65 +80,17 @@
     APR_RING_HEAD(pfd_dead_ring_t, pfd_elem_t) dead_ring;
 };
 
-static apr_status_t backend_cleanup(void *p_)
+static apr_status_t impl_pollset_cleanup(apr_pollset_t *pollset)
 {
-    apr_pollset_t *pollset = (apr_pollset_t *) p_;
-    close(pollset->epoll_fd);
-    if (pollset->flags & APR_POLLSET_WAKEABLE) {
-        /* Close both sides of the wakeup pipe */
-        if (pollset->wakeup_pipe[0]) {
-            apr_file_close(pollset->wakeup_pipe[0]);
-            pollset->wakeup_pipe[0] = NULL;
-        }
-        if (pollset->wakeup_pipe[1]) {
-            apr_file_close(pollset->wakeup_pipe[1]);
-            pollset->wakeup_pipe[1] = NULL;
-        }
-    }
+    close(pollset->p->epoll_fd);
     return APR_SUCCESS;
 }
 
-/* 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];
-    /* Add the pipe to the pollset
-     */
-    return apr_pollset_add(pollset, &fd);
-}
-
-/* Read and discard what's ever in the wakeup pipe.
- */
-static void 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;
-    }
-}
 
-APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
-                                             apr_uint32_t size,
-                                             apr_pool_t *p,
-                                             apr_uint32_t flags)
+static apr_status_t impl_pollset_create(apr_pollset_t *pollset,
+                                        apr_uint32_t size,
+                                        apr_pool_t *p,
+                                        apr_uint32_t flags)
 {
     apr_status_t rv;
     int fd;
@@ -149,58 +101,40 @@
     }
     fd = epoll_create(size);
     if (fd < 0) {
-        *pollset = NULL;
+        pollset->p = NULL;
         return errno;
     }
 
-    *pollset = apr_palloc(p, sizeof(**pollset));
+    pollset->p = apr_palloc(p, sizeof(apr_pollset_private_t));
 #if APR_HAS_THREADS
     if ((flags & APR_POLLSET_THREADSAFE) &&
         !(flags & APR_POLLSET_NOCOPY) &&
-        ((rv = apr_thread_mutex_create(&(*pollset)->ring_lock,
+        ((rv = apr_thread_mutex_create(&pollset->p->ring_lock,
                                        APR_THREAD_MUTEX_DEFAULT,
                                        p)) != APR_SUCCESS)) {
-        *pollset = NULL;
+        pollset->p = NULL;
         return rv;
     }
 #else
     if (flags & APR_POLLSET_THREADSAFE) {
-        *pollset = NULL;
+        pollset->p = NULL;
         return APR_ENOTIMPL;
     }
 #endif
-    (*pollset)->nelts = 0;
-    (*pollset)->nalloc = size;
-    (*pollset)->flags = flags;
-    (*pollset)->pool = p;
-    (*pollset)->epoll_fd = fd;
-    (*pollset)->pollset = apr_palloc(p, size * sizeof(struct epoll_event));
-    (*pollset)->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
+    pollset->p->epoll_fd = fd;
+    pollset->p->pollset = apr_palloc(p, size * sizeof(struct epoll_event));
+    pollset->p->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
 
     if (!(flags & APR_POLLSET_NOCOPY)) {
-        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);
+        APR_RING_INIT(&pollset->p->query_ring, pfd_elem_t, link);
+        APR_RING_INIT(&pollset->p->free_ring, pfd_elem_t, link);
+        APR_RING_INIT(&pollset->p->dead_ring, pfd_elem_t, link);
     }
-    if (flags & APR_POLLSET_WAKEABLE) {
-        /* Create wakeup pipe */
-        if ((rv = create_wakeup_pipe(*pollset)) != APR_SUCCESS) {
-            close(fd);
-            *pollset = NULL;
-            return rv;
-        }
-    }
-    apr_pool_cleanup_register(p, *pollset, backend_cleanup, backend_cleanup);
     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)
+static apr_status_t impl_pollset_add(apr_pollset_t *pollset,
+                                     const apr_pollfd_t *descriptor)
 {
     struct epoll_event ev = {0};
     int ret = -1;
@@ -215,8 +149,8 @@
     else {
         pollset_lock_rings();
 
-        if (!APR_RING_EMPTY(&(pollset->free_ring), pfd_elem_t, link)) {
-            elem = APR_RING_FIRST(&(pollset->free_ring));
+        if (!APR_RING_EMPTY(&(pollset->p->free_ring), pfd_elem_t, link)) {
+            elem = APR_RING_FIRST(&(pollset->p->free_ring));
             APR_RING_REMOVE(elem, link);
         }
         else {
@@ -227,11 +161,11 @@
         ev.data.ptr = elem;
     }
     if (descriptor->desc_type == APR_POLL_SOCKET) {
-        ret = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_ADD,
+        ret = epoll_ctl(pollset->p->epoll_fd, EPOLL_CTL_ADD,
                         descriptor->desc.s->socketdes, &ev);
     }
     else {
-        ret = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_ADD,
+        ret = epoll_ctl(pollset->p->epoll_fd, EPOLL_CTL_ADD,
                         descriptor->desc.f->filedes, &ev);
     }
 
@@ -243,11 +177,11 @@
     else {
         if (0 != ret) {
             rv = APR_EBADF;
-            APR_RING_INSERT_TAIL(&(pollset->free_ring), elem, pfd_elem_t, link);
+            APR_RING_INSERT_TAIL(&(pollset->p->free_ring), elem, pfd_elem_t, link);
         }
         else {
             pollset->nelts++;
-            APR_RING_INSERT_TAIL(&(pollset->query_ring), elem, pfd_elem_t, link);
+            APR_RING_INSERT_TAIL(&(pollset->p->query_ring), elem, pfd_elem_t, link);
         }
         pollset_unlock_rings();
     }
@@ -255,8 +189,8 @@
     return rv;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
-                                             const apr_pollfd_t *descriptor)
+static apr_status_t impl_pollset_remove(apr_pollset_t *pollset,
+                                        const apr_pollfd_t *descriptor)
 {
     pfd_elem_t *ep;
     apr_status_t rv = APR_SUCCESS;
@@ -266,11 +200,11 @@
     ev.events = get_epoll_event(descriptor->reqevents);
 
     if (descriptor->desc_type == APR_POLL_SOCKET) {
-        ret = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_DEL,
+        ret = epoll_ctl(pollset->p->epoll_fd, EPOLL_CTL_DEL,
                         descriptor->desc.s->socketdes, &ev);
     }
     else {
-        ret = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_DEL,
+        ret = epoll_ctl(pollset->p->epoll_fd, EPOLL_CTL_DEL,
                         descriptor->desc.f->filedes, &ev);
     }
     if (ret < 0) {
@@ -280,15 +214,15 @@
     if (!(pollset->flags & APR_POLLSET_NOCOPY)) {
         pollset_lock_rings();
 
-        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),
+        if (!APR_RING_EMPTY(&(pollset->p->query_ring), pfd_elem_t, link)) {
+            for (ep = APR_RING_FIRST(&(pollset->p->query_ring));
+                 ep != APR_RING_SENTINEL(&(pollset->p->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),
+                    APR_RING_INSERT_TAIL(&(pollset->p->dead_ring),
                                          ep, pfd_elem_t, link);
                     break;
                 }
@@ -301,7 +235,7 @@
     return rv;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset,
+static apr_status_t impl_pollset_poll(apr_pollset_t *pollset,
                                            apr_interval_time_t timeout,
                                            apr_int32_t *num,
                                            const apr_pollfd_t **descriptors)
@@ -314,7 +248,7 @@
         timeout /= 1000;
     }
 
-    ret = epoll_wait(pollset->epoll_fd, pollset->pollset, pollset->nalloc,
+    ret = epoll_wait(pollset->p->epoll_fd, pollset->p->pollset, pollset->nalloc,
                      timeout);
     (*num) = ret;
 
@@ -327,20 +261,20 @@
     else {
         if (pollset->flags & APR_POLLSET_NOCOPY) {
             for (i = 0, j = 0; i < ret; i++) {
-                fd = *((apr_pollfd_t *) (pollset->pollset[i].data.ptr));
+                fd = *((apr_pollfd_t *)(pollset->p->pollset[i].data.ptr));
                /* Check if the polled descriptor is our
                  * wakeup pipe. In that case do not put it result set.
                  */
                 if ((pollset->flags & APR_POLLSET_WAKEABLE) &&
                     fd.desc_type == APR_POLL_FILE &&
                     fd.desc.f == pollset->wakeup_pipe[0]) {
-                        drain_wakeup_pipe(pollset);
+                        apr_pollset_drain_wakeup_pipe(pollset);
                         rv = APR_EINTR;
                 }
                 else {
-                    pollset->result_set[j] = fd;
-                    pollset->result_set[j].rtnevents =
-                        get_epoll_revent(pollset->pollset[i].events);
+                    pollset->p->result_set[j] = fd;
+                    pollset->p->result_set[j].rtnevents =
+                        get_epoll_revent(pollset->p->pollset[i].events);
                     j++;
                 }
             }
@@ -349,17 +283,17 @@
         }
         else {
             for (i = 0, j = 0; i < ret; i++) {
-                fd = (((pfd_elem_t *) (pollset->pollset[i].data.ptr))->pfd);
+                fd = (((pfd_elem_t *) (pollset->p->pollset[i].data.ptr))->pfd);
                 if ((pollset->flags & APR_POLLSET_WAKEABLE) &&
                     fd.desc_type == APR_POLL_FILE &&
                     fd.desc.f == pollset->wakeup_pipe[0]) {
-                        drain_wakeup_pipe(pollset);
+                        apr_pollset_drain_wakeup_pipe(pollset);
                         rv = APR_EINTR;
                 }
                 else {
-                    pollset->result_set[j] = fd;
-                    pollset->result_set[j].rtnevents =
-                        get_epoll_revent(pollset->pollset[i].events);
+                    pollset->p->result_set[j] = fd;
+                    pollset->p->result_set[j].rtnevents =
+                        get_epoll_revent(pollset->p->pollset[i].events);
                     j++;
                 }
             }
@@ -368,7 +302,7 @@
         }
 
         if (descriptors) {
-            *descriptors = pollset->result_set;
+            *descriptors = pollset->p->result_set;
         }
     }
 
@@ -376,7 +310,7 @@
         pollset_lock_rings();
 
         /* Shift all PFDs in the Dead Ring to be Free Ring */
-        APR_RING_CONCAT(&(pollset->free_ring), &(pollset->dead_ring), pfd_elem_t, link);
+        APR_RING_CONCAT(&(pollset->p->free_ring), &(pollset->p->dead_ring), pfd_elem_t, link);
 
         pollset_unlock_rings();
     }
@@ -384,54 +318,46 @@
     return rv;
 }
 
-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;
-}
-
-struct apr_pollcb_t {
-    apr_pool_t *pool;
-    apr_uint32_t nalloc;
-    struct epoll_event *pollset;
-    int epoll_fd;
+static apr_pollset_provider_t impl = {
+    impl_pollset_create,
+    impl_pollset_add,
+    impl_pollset_remove,
+    impl_pollset_poll,
+    impl_pollset_cleanup,
+    "epool"
 };
 
+apr_pollset_provider_t *apr_pollset_provider_epoll = &impl;
+
 static apr_status_t cb_cleanup(void *p_)
 {
     apr_pollcb_t *pollcb = (apr_pollcb_t *) p_;
-    close(pollcb->epoll_fd);
+    close(pollcb->fd);
     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)
+static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb,
+                                       apr_uint32_t size,
+                                       apr_pool_t *p,
+                                       apr_uint32_t flags)
 {
     int fd;
     
     fd = epoll_create(size);
     
     if (fd < 0) {
-        *pollcb = NULL;
         return apr_get_netos_error();
     }
     
-    *pollcb = apr_palloc(p, sizeof(**pollcb));
-    (*pollcb)->nalloc = size;
-    (*pollcb)->pool = p;
-    (*pollcb)->epoll_fd = fd;
-    (*pollcb)->pollset = apr_palloc(p, size * sizeof(struct epoll_event));
-    apr_pool_cleanup_register(p, *pollcb, cb_cleanup, cb_cleanup);
+    pollcb->fd = fd;
+    pollcb->pollset.epoll = apr_palloc(p, size * sizeof(struct epoll_event));
+    apr_pool_cleanup_register(p, pollcb, cb_cleanup, cb_cleanup);
 
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb,
-                                         apr_pollfd_t *descriptor)
+static apr_status_t impl_pollcb_add(apr_pollcb_t *pollcb,
+                                    apr_pollfd_t *descriptor)
 {
     struct epoll_event ev;
     int ret;
@@ -440,11 +366,11 @@
     ev.data.ptr = (void *)descriptor;
 
     if (descriptor->desc_type == APR_POLL_SOCKET) {
-        ret = epoll_ctl(pollcb->epoll_fd, EPOLL_CTL_ADD,
+        ret = epoll_ctl(pollcb->fd, EPOLL_CTL_ADD,
                         descriptor->desc.s->socketdes, &ev);
     }
     else {
-        ret = epoll_ctl(pollcb->epoll_fd, EPOLL_CTL_ADD,
+        ret = epoll_ctl(pollcb->fd, EPOLL_CTL_ADD,
                         descriptor->desc.f->filedes, &ev);
     }
     
@@ -455,8 +381,8 @@
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb,
-                                            apr_pollfd_t *descriptor)
+static apr_status_t impl_pollcb_remove(apr_pollcb_t *pollcb,
+                                       apr_pollfd_t *descriptor)
 {
     apr_status_t rv = APR_SUCCESS;
     struct epoll_event ev;
@@ -465,11 +391,11 @@
     ev.events = get_epoll_event(descriptor->reqevents);
     
     if (descriptor->desc_type == APR_POLL_SOCKET) {
-        ret = epoll_ctl(pollcb->epoll_fd, EPOLL_CTL_DEL,
+        ret = epoll_ctl(pollcb->fd, EPOLL_CTL_DEL,
                         descriptor->desc.s->socketdes, &ev);
     }
     else {
-        ret = epoll_ctl(pollcb->epoll_fd, EPOLL_CTL_DEL,
+        ret = epoll_ctl(pollcb->fd, EPOLL_CTL_DEL,
                         descriptor->desc.f->filedes, &ev);
     }
     
@@ -481,10 +407,10 @@
 }
 
 
-APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb,
-                                          apr_interval_time_t timeout,
-                                          apr_pollcb_cb_t func,
-                                          void *baton)
+static apr_status_t impl_pollcb_poll(apr_pollcb_t *pollcb,
+                                     apr_interval_time_t timeout,
+                                     apr_pollcb_cb_t func,
+                                     void *baton)
 {
     int ret, i;
     apr_status_t rv = APR_SUCCESS;
@@ -493,7 +419,7 @@
         timeout /= 1000;
     }
     
-    ret = epoll_wait(pollcb->epoll_fd, pollcb->pollset, pollcb->nalloc,
+    ret = epoll_wait(pollcb->fd, pollcb->pollset.epoll, pollcb->nalloc,
                      timeout);
     if (ret < 0) {
         rv = apr_get_netos_error();
@@ -503,8 +429,8 @@
     }
     else {
         for (i = 0; i < ret; i++) {
-            apr_pollfd_t *pollfd = (apr_pollfd_t *)(pollcb->pollset[i].data.ptr);
-            pollfd->rtnevents = get_epoll_revent(pollcb->pollset[i].events);
+            apr_pollfd_t *pollfd = (apr_pollfd_t *)(pollcb->pollset.epoll[i].data.ptr);
+            pollfd->rtnevents = get_epoll_revent(pollcb->pollset.epoll[i].events);
 
             rv = func(baton, pollfd);
             if (rv) {
@@ -516,4 +442,14 @@
     return rv;
 }
 
-#endif /* POLLSET_USES_EPOLL */
+static apr_pollcb_provider_t impl_cb = {
+    impl_pollcb_create,
+    impl_pollcb_add,
+    impl_pollcb_remove,
+    impl_pollcb_poll,
+    "epoll"
+};
+
+apr_pollcb_provider_t *apr_pollcb_provider_epoll = &impl_cb;
+
+#endif /* HAVE_EPOLL */

Modified: apr/apr/trunk/poll/unix/kqueue.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/poll/unix/kqueue.c?rev=744095&r1=744094&r2=744095&view=diff
==============================================================================
--- apr/apr/trunk/poll/unix/kqueue.c (original)
+++ apr/apr/trunk/poll/unix/kqueue.c Fri Feb 13 12:24:00 2009
@@ -14,9 +14,15 @@
  * limitations under the License.
  */
 
+#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"
 
-#ifdef POLLSET_USES_KQUEUE
+#ifdef HAVE_KQUEUE
 
 static apr_int16_t get_kqueue_revent(apr_int16_t event, apr_int16_t flags)
 {
@@ -34,18 +40,12 @@
     return rv;
 }
 
-struct apr_pollset_t
+struct apr_pollset_private_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;
-    /* Pipe descriptors used for wakeup */
-    apr_file_t *wakeup_pipe[2];
 #if APR_HAS_THREADS
     /* A thread mutex to protect operations on the rings */
     apr_thread_mutex_t *ring_lock;
@@ -59,129 +59,56 @@
     APR_RING_HEAD(pfd_dead_ring_t, pfd_elem_t) dead_ring;
 };
 
-static apr_status_t backend_cleanup(void *p_)
+static apr_status_t impl_pollset_cleanup(apr_pollset_t *pollset)
 {
-    apr_pollset_t *pollset = (apr_pollset_t *) p_;
-    close(pollset->kqueue_fd);
-    if (pollset->flags & APR_POLLSET_WAKEABLE) {
-        /* Close both sides of the wakeup pipe */
-        if (pollset->wakeup_pipe[0]) {
-            apr_file_close(pollset->wakeup_pipe[0]);
-            pollset->wakeup_pipe[0] = NULL;
-        }
-        if (pollset->wakeup_pipe[1]) {
-            apr_file_close(pollset->wakeup_pipe[1]);
-            pollset->wakeup_pipe[1] = NULL;
-        }
-    }
+    close(pollset->p->kqueue_fd);
     return APR_SUCCESS;
 }
 
-/* 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];
-    /* Add the pipe to the pollset
-     */
-    return apr_pollset_add(pollset, &fd);
-}
-
-/* Read and discard what's ever in the wakeup pipe.
- */
-static void 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;
-    }
-}
-
-APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
-                                             apr_uint32_t size,
-                                             apr_pool_t *p,
-                                             apr_uint32_t flags)
+static apr_status_t impl_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));
+    pollset->p = apr_palloc(p, sizeof(apr_pollset_private_t));
 #if APR_HAS_THREADS
     if (flags & APR_POLLSET_THREADSAFE &&
-        ((rv = apr_thread_mutex_create(&(*pollset)->ring_lock,
+        ((rv = apr_thread_mutex_create(&pollset->p->ring_lock,
                                        APR_THREAD_MUTEX_DEFAULT,
                                        p)) != APR_SUCCESS)) {
-        *pollset = NULL;
+        pollset->p = NULL;
         return rv;
     }
 #else
     if (flags & APR_POLLSET_THREADSAFE) {
-        *pollset = NULL;
+        pollset->p = NULL;
         return APR_ENOTIMPL;
     }
 #endif
-    if (flags & APR_POLLSET_WAKEABLE) {
-        /* Add room for wakeup descriptor */
-        size++;
-    }
 
-    (*pollset)->nelts = 0;
-    (*pollset)->nalloc = size;
-    (*pollset)->flags = flags;
-    (*pollset)->pool = p;
-
-    (*pollset)->ke_set =
+    pollset->p->ke_set =
         (struct kevent *) apr_palloc(p, size * sizeof(struct kevent));
 
-    memset((*pollset)->ke_set, 0, size * sizeof(struct kevent));
+    memset(pollset->p->ke_set, 0, size * sizeof(struct kevent));
 
-    (*pollset)->kqueue_fd = kqueue();
+    pollset->p->kqueue_fd = kqueue();
 
-    if ((*pollset)->kqueue_fd == -1) {
+    if (pollset->p->kqueue_fd == -1) {
         return apr_get_netos_error();
     }
 
-    (*pollset)->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
+    pollset->p->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);
-    if (flags & APR_POLLSET_WAKEABLE) {
-        /* Create wakeup pipe */
-        if ((rv = create_wakeup_pipe(*pollset)) != APR_SUCCESS) {
-            close((*pollset)->kqueue_fd);
-            *pollset = NULL;
-            return rv;
-        }
-    }
-    apr_pool_cleanup_register(p, (void *) (*pollset), backend_cleanup,
-                              apr_pool_cleanup_null);
+    APR_RING_INIT(&pollset->p->query_ring, pfd_elem_t, link);
+    APR_RING_INIT(&pollset->p->free_ring, pfd_elem_t, link);
+    APR_RING_INIT(&pollset->p->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)
+static apr_status_t impl_pollset_add(apr_pollset_t *pollset,
+                                     const apr_pollfd_t *descriptor)
 {
     apr_os_sock_t fd;
     pfd_elem_t *elem;
@@ -189,8 +116,8 @@
 
     pollset_lock_rings();
 
-    if (!APR_RING_EMPTY(&(pollset->free_ring), pfd_elem_t, link)) {
-        elem = APR_RING_FIRST(&(pollset->free_ring));
+    if (!APR_RING_EMPTY(&(pollset->p->free_ring), pfd_elem_t, link)) {
+        elem = APR_RING_FIRST(&(pollset->p->free_ring));
         APR_RING_REMOVE(elem, link);
     }
     else {
@@ -207,18 +134,18 @@
     }
 
     if (descriptor->reqevents & APR_POLLIN) {
-        EV_SET(&pollset->kevent, fd, EVFILT_READ, EV_ADD, 0, 0, elem);
+        EV_SET(&pollset->p->kevent, fd, EVFILT_READ, EV_ADD, 0, 0, elem);
 
-        if (kevent(pollset->kqueue_fd, &pollset->kevent, 1, NULL, 0,
+        if (kevent(pollset->p->kqueue_fd, &pollset->p->kevent, 1, NULL, 0,
                    NULL) == -1) {
             rv = apr_get_netos_error();
         }
     }
 
     if (descriptor->reqevents & APR_POLLOUT && rv == APR_SUCCESS) {
-        EV_SET(&pollset->kevent, fd, EVFILT_WRITE, EV_ADD, 0, 0, elem);
+        EV_SET(&pollset->p->kevent, fd, EVFILT_WRITE, EV_ADD, 0, 0, elem);
 
-        if (kevent(pollset->kqueue_fd, &pollset->kevent, 1, NULL, 0,
+        if (kevent(pollset->p->kqueue_fd, &pollset->p->kevent, 1, NULL, 0,
                    NULL) == -1) {
             rv = apr_get_netos_error();
         }
@@ -226,10 +153,10 @@
 
     if (rv == APR_SUCCESS) {
         pollset->nelts++;
-        APR_RING_INSERT_TAIL(&(pollset->query_ring), elem, pfd_elem_t, link);
+        APR_RING_INSERT_TAIL(&(pollset->p->query_ring), elem, pfd_elem_t, link);
     }
     else {
-        APR_RING_INSERT_TAIL(&(pollset->free_ring), elem, pfd_elem_t, link);
+        APR_RING_INSERT_TAIL(&(pollset->p->free_ring), elem, pfd_elem_t, link);
     }
 
     pollset_unlock_rings();
@@ -237,8 +164,8 @@
     return rv;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
-                                             const apr_pollfd_t *descriptor)
+static apr_status_t impl_pollset_remove(apr_pollset_t *pollset,
+                                        const apr_pollfd_t *descriptor)
 {
     pfd_elem_t *ep;
     apr_status_t rv = APR_SUCCESS;
@@ -254,32 +181,32 @@
     }
 
     if (descriptor->reqevents & APR_POLLIN) {
-        EV_SET(&pollset->kevent, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
+        EV_SET(&pollset->p->kevent, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
 
-        if (kevent(pollset->kqueue_fd, &pollset->kevent, 1, NULL, 0,
+        if (kevent(pollset->p->kqueue_fd, &pollset->p->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);
+        EV_SET(&pollset->p->kevent, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
 
-        if (kevent(pollset->kqueue_fd, &pollset->kevent, 1, NULL, 0,
+        if (kevent(pollset->p->kqueue_fd, &pollset->p->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),
+    if (!APR_RING_EMPTY(&(pollset->p->query_ring), pfd_elem_t, link)) {
+        for (ep = APR_RING_FIRST(&(pollset->p->query_ring));
+             ep != APR_RING_SENTINEL(&(pollset->p->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),
+                APR_RING_INSERT_TAIL(&(pollset->p->dead_ring),
                                      ep, pfd_elem_t, link);
                 break;
             }
@@ -291,10 +218,10 @@
     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)
+static apr_status_t impl_pollset_poll(apr_pollset_t *pollset,
+                                      apr_interval_time_t timeout,
+                                      apr_int32_t *num,
+                                      const apr_pollfd_t **descriptors)
 {
     int ret, i, j;
     struct timespec tv, *tvptr;
@@ -310,8 +237,8 @@
         tvptr = &tv;
     }
 
-    ret = kevent(pollset->kqueue_fd, NULL, 0, pollset->ke_set, pollset->nalloc,
-                tvptr);
+    ret = kevent(pollset->p->kqueue_fd, NULL, 0, pollset->p->ke_set,
+                 pollset->nalloc, tvptr);
     (*num) = ret;
     if (ret < 0) {
         rv = apr_get_netos_error();
@@ -321,25 +248,25 @@
     }
     else {
         for (i = 0, j = 0; i < ret; i++) {
-            fd = (((pfd_elem_t*)(pollset->ke_set[i].udata))->pfd);
+            fd = (((pfd_elem_t*)(pollset->p->ke_set[i].udata))->pfd);
             if ((pollset->flags & APR_POLLSET_WAKEABLE) &&
                 fd.desc_type == APR_POLL_FILE &&
                 fd.desc.f == pollset->wakeup_pipe[0]) {
-                drain_wakeup_pipe(pollset);
+                apr_pollset_drain_wakeup_pipe(pollset);
                 rv = APR_EINTR;
             }
             else {
-                pollset->result_set[j] = fd;
-                pollset->result_set[j].rtnevents =
-                        get_kqueue_revent(pollset->ke_set[i].filter,
-                                          pollset->ke_set[i].flags);
+                pollset->p->result_set[j] = fd;
+                pollset->p->result_set[j].rtnevents =
+                        get_kqueue_revent(pollset->p->ke_set[i].filter,
+                                          pollset->p->ke_set[i].flags);
                 j++;
             }
         }
         if ((*num = j))
             rv = APR_SUCCESS;
         if (descriptors) {
-            *descriptors = pollset->result_set;
+            *descriptors = pollset->p->result_set;
         }
     }
 
@@ -347,61 +274,54 @@
     pollset_lock_rings();
 
     /* Shift all PFDs in the Dead Ring to be Free Ring */
-    APR_RING_CONCAT(&(pollset->free_ring), &(pollset->dead_ring), pfd_elem_t, link);
+    APR_RING_CONCAT(&(pollset->p->free_ring), &(pollset->p->dead_ring),
+                    pfd_elem_t, link);
 
     pollset_unlock_rings();
 
     return rv;
 }
 
-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;
-}
-
-struct apr_pollcb_t {
-    apr_pool_t *pool;
-    apr_uint32_t nalloc;
-    struct kevent *pollset;
-    int kqfd;
+static apr_pollset_provider_t impl = {
+    impl_pollset_create,
+    impl_pollset_add,
+    impl_pollset_remove,
+    impl_pollset_poll,
+    impl_pollset_cleanup,
+    "kqueue"
 };
 
+apr_pollset_provider_t *apr_pollset_provider_kqueue = &impl;
+
 static apr_status_t cb_cleanup(void *b_)
 {
     apr_pollcb_t *pollcb = (apr_pollcb_t *) b_;
-    close(pollcb->kqfd);
+    close(pollcb->fd);
     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)
+static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb,
+                                       apr_uint32_t size,
+                                       apr_pool_t *p,
+                                       apr_uint32_t flags)
 {
     int fd;
     
     fd = kqueue();
     if (fd < 0) {
-        *pollcb = NULL;
         return apr_get_netos_error();
     }
     
-    *pollcb = apr_palloc(p, sizeof(**pollcb));
-    (*pollcb)->nalloc = size;
-    (*pollcb)->pool = p;
-    (*pollcb)->kqfd = fd;
-    (*pollcb)->pollset = (struct kevent *)apr_pcalloc(p, size * sizeof(struct kevent));
-    apr_pool_cleanup_register(p, *pollcb, cb_cleanup, cb_cleanup);
+    pollcb->fd = fd;
+    pollcb->pollset.ke = (struct kevent *)apr_pcalloc(p, size * sizeof(struct kevent));
+    apr_pool_cleanup_register(p, pollcb, cb_cleanup, cb_cleanup);
     
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb,
-                                         apr_pollfd_t *descriptor)
+static apr_status_t impl_pollcb_add(apr_pollcb_t *pollcb,
+                                    apr_pollfd_t *descriptor)
 {
     apr_os_sock_t fd;
     struct kevent ev;
@@ -417,7 +337,7 @@
     if (descriptor->reqevents & APR_POLLIN) {
         EV_SET(&ev, fd, EVFILT_READ, EV_ADD, 0, 0, descriptor);
         
-        if (kevent(pollcb->kqfd, &ev, 1, NULL, 0, NULL) == -1) {
+        if (kevent(pollcb->fd, &ev, 1, NULL, 0, NULL) == -1) {
             rv = apr_get_netos_error();
         }
     }
@@ -425,7 +345,7 @@
     if (descriptor->reqevents & APR_POLLOUT && rv == APR_SUCCESS) {
         EV_SET(&ev, fd, EVFILT_WRITE, EV_ADD, 0, 0, descriptor);
         
-        if (kevent(pollcb->kqfd, &ev, 1, NULL, 0, NULL) == -1) {
+        if (kevent(pollcb->fd, &ev, 1, NULL, 0, NULL) == -1) {
             rv = apr_get_netos_error();
         }
     }
@@ -433,8 +353,8 @@
     return rv;
 }
 
-APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb,
-                                            apr_pollfd_t *descriptor)
+static apr_status_t impl_pollcb_remove(apr_pollcb_t *pollcb,
+                                       apr_pollfd_t *descriptor)
 {
     apr_status_t rv = APR_SUCCESS;
     struct kevent ev;
@@ -450,7 +370,7 @@
     if (descriptor->reqevents & APR_POLLIN) {
         EV_SET(&ev, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
         
-        if (kevent(pollcb->kqfd, &ev, 1, NULL, 0, NULL) == -1) {
+        if (kevent(pollcb->fd, &ev, 1, NULL, 0, NULL) == -1) {
             rv = APR_NOTFOUND;
         }
     }
@@ -461,7 +381,7 @@
          */
         EV_SET(&ev, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
         
-        if (kevent(pollcb->kqfd, &ev, 1, NULL, 0, NULL) == -1) {
+        if (kevent(pollcb->fd, &ev, 1, NULL, 0, NULL) == -1) {
             rv = APR_NOTFOUND;
         }
     }
@@ -470,10 +390,10 @@
 }
 
 
-APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb,
-                                          apr_interval_time_t timeout,
-                                          apr_pollcb_cb_t func,
-                                          void *baton)
+static apr_status_t impl_pollcb_poll(apr_pollcb_t *pollcb,
+                                     apr_interval_time_t timeout,
+                                     apr_pollcb_cb_t func,
+                                     void *baton)
 {
     int ret, i;
     struct timespec tv, *tvptr;
@@ -488,7 +408,7 @@
         tvptr = &tv;
     }
     
-    ret = kevent(pollcb->kqfd, NULL, 0, pollcb->pollset, pollcb->nalloc,
+    ret = kevent(pollcb->fd, NULL, 0, pollcb->pollset.ke, pollcb->nalloc,
                  tvptr);
 
     if (ret < 0) {
@@ -499,10 +419,10 @@
     }
     else {
         for (i = 0; i < ret; i++) {
-            apr_pollfd_t *pollfd = (apr_pollfd_t *)(pollcb->pollset[i].udata);
+            apr_pollfd_t *pollfd = (apr_pollfd_t *)(pollcb->pollset.ke[i].udata);
             
-            pollfd->rtnevents = get_kqueue_revent(pollcb->pollset[i].filter,
-                                                  pollcb->pollset[i].flags);
+            pollfd->rtnevents = get_kqueue_revent(pollcb->pollset.ke[i].filter,
+                                                  pollcb->pollset.ke[i].flags);
             
             rv = func(baton, pollfd);
             
@@ -515,4 +435,14 @@
     return rv;
 }
 
-#endif /* POLLSET_USES_KQUEUE */
+static apr_pollcb_provider_t impl_cb = {
+    impl_pollcb_create,
+    impl_pollcb_add,
+    impl_pollcb_remove,
+    impl_pollcb_poll,
+    "kqueue"
+};
+
+apr_pollcb_provider_t *apr_pollcb_provider_kqueue = &impl_cb;
+
+#endif /* HAVE_KQUEUE */

Modified: apr/apr/trunk/poll/unix/poll.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/poll/unix/poll.c?rev=744095&r1=744094&r2=744095&view=diff
==============================================================================
--- apr/apr/trunk/poll/unix/poll.c (original)
+++ apr/apr/trunk/poll/unix/poll.c Fri Feb 13 12:24:00 2009
@@ -14,9 +14,16 @@
  * limitations under the License.
  */
 
+#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_misc.h"
 #include "apr_arch_poll_private.h"
 
-#if defined(POLL_USES_POLL) || defined(POLLSET_USES_POLL)
+#if defined(HAVE_POLL)
 
 #ifdef HAVE_ALLOCA_H
 #include <alloca.h>
@@ -62,9 +69,6 @@
     return rv;
 }
 
-#endif /* POLL_USES_POLL || POLLSET_USES_POLL */
-
-
 #ifdef POLL_USES_POLL
 
 #define SMALL_POLLSET_LIMIT  8
@@ -148,163 +152,70 @@
 
 #endif /* POLL_USES_POLL */
 
-
-#ifdef POLLSET_USES_POLL
-
-struct apr_pollset_t
+struct apr_pollset_private_t
 {
-    apr_pool_t *pool;
-    apr_uint32_t nelts;
-    apr_uint32_t nalloc;
-    apr_uint32_t flags;
-    /* Pipe descriptors used for wakeup */
-    apr_file_t *wakeup_pipe[2];    
     struct pollfd *pollset;
     apr_pollfd_t *query_set;
     apr_pollfd_t *result_set;
 };
 
-/* 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];
-    /* Add the pipe to the pollset
-     */
-    return apr_pollset_add(pollset, &fd);
-}
-
-/* Read and discard what's ever in the wakeup pipe.
- */
-static void 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 wakeup_pipe_cleanup(void *p)
-{
-    apr_pollset_t *pollset = (apr_pollset_t *) p;
-    if (pollset->flags & APR_POLLSET_WAKEABLE) {
-        /* Close both sides of the wakeup pipe */
-        if (pollset->wakeup_pipe[0]) {
-            apr_file_close(pollset->wakeup_pipe[0]);
-            pollset->wakeup_pipe[0] = NULL;
-        }
-        if (pollset->wakeup_pipe[1]) {
-            apr_file_close(pollset->wakeup_pipe[1]);
-            pollset->wakeup_pipe[1] = NULL;
-        }
-    }
-
-    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)
+static apr_status_t impl_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;
     }
-    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)->pollset = apr_palloc(p, size * sizeof(struct pollfd));
-    (*pollset)->query_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
-    (*pollset)->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
-
-    if (flags & APR_POLLSET_WAKEABLE) {
-        apr_status_t rv;
-        /* Create wakeup pipe */
-        if ((rv = create_wakeup_pipe(*pollset)) != APR_SUCCESS) {
-            *pollset = NULL;
-            return rv;
-        }
-        apr_pool_cleanup_register(p, *pollset, wakeup_pipe_cleanup,
-                                  apr_pool_cleanup_null);
-    }
-    return APR_SUCCESS;
-}
+    pollset->p = apr_palloc(p, sizeof(apr_pollset_private_t));
+    pollset->p->pollset = apr_palloc(p, size * sizeof(struct pollfd));
+    pollset->p->query_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
+    pollset->p->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
 
-APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset)
-{
-    if (pollset->flags & APR_POLLSET_WAKEABLE) 
-        return apr_pool_cleanup_run(pollset->pool, pollset,
-                                    wakeup_pipe_cleanup);
-    else
-        return APR_SUCCESS;
+    return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset,
-                                          const apr_pollfd_t *descriptor)
+static apr_status_t impl_pollset_add(apr_pollset_t *pollset,
+                                     const apr_pollfd_t *descriptor)
 {
     if (pollset->nelts == pollset->nalloc) {
         return APR_ENOMEM;
     }
 
-    pollset->query_set[pollset->nelts] = *descriptor;
+    pollset->p->query_set[pollset->nelts] = *descriptor;
 
     if (descriptor->desc_type == APR_POLL_SOCKET) {
-        pollset->pollset[pollset->nelts].fd = descriptor->desc.s->socketdes;
+        pollset->p->pollset[pollset->nelts].fd = descriptor->desc.s->socketdes;
     }
     else {
-        pollset->pollset[pollset->nelts].fd = descriptor->desc.f->filedes;
+        pollset->p->pollset[pollset->nelts].fd = descriptor->desc.f->filedes;
     }
 
-    pollset->pollset[pollset->nelts].events =
+    pollset->p->pollset[pollset->nelts].events =
         get_event(descriptor->reqevents);
     pollset->nelts++;
 
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
-                                             const apr_pollfd_t *descriptor)
+static apr_status_t impl_pollset_remove(apr_pollset_t *pollset,
+                                        const apr_pollfd_t *descriptor)
 {
     apr_uint32_t i;
 
     for (i = 0; i < pollset->nelts; i++) {
-        if (descriptor->desc.s == pollset->query_set[i].desc.s) {
+        if (descriptor->desc.s == pollset->p->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) {
+                if (descriptor->desc.s == pollset->p->query_set[i].desc.s) {
                     pollset->nelts--;
                 }
                 else {
-                    pollset->pollset[dst] = pollset->pollset[i];
-                    pollset->query_set[dst] = pollset->query_set[i];
+                    pollset->p->pollset[dst] = pollset->p->pollset[i];
+                    pollset->p->query_set[dst] = pollset->p->query_set[i];
                     dst++;
                 }
             }
@@ -315,10 +226,10 @@
     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)
+static apr_status_t impl_pollset_poll(apr_pollset_t *pollset,
+                                      apr_interval_time_t timeout,
+                                      apr_int32_t *num,
+                                      const apr_pollfd_t **descriptors)
 {
     int ret;
     apr_status_t rv = APR_SUCCESS;
@@ -327,7 +238,7 @@
     if (timeout > 0) {
         timeout /= 1000;
     }
-    ret = poll(pollset->pollset, pollset->nelts, timeout);
+    ret = poll(pollset->p->pollset, pollset->nelts, timeout);
     (*num) = ret;
     if (ret < 0) {
         return apr_get_netos_error();
@@ -337,20 +248,20 @@
     }
     else {
         for (i = 0, j = 0; i < pollset->nelts; i++) {
-            if (pollset->pollset[i].revents != 0) {
+            if (pollset->p->pollset[i].revents != 0) {
                 /* Check if the polled descriptor is our
                  * wakeup pipe. In that case do not put it result set.
                  */
                 if ((pollset->flags & APR_POLLSET_WAKEABLE) &&
-                    pollset->query_set[i].desc_type == APR_POLL_FILE &&
-                    pollset->query_set[i].desc.f == pollset->wakeup_pipe[0]) {
-                        drain_wakeup_pipe(pollset);
+                    pollset->p->query_set[i].desc_type == APR_POLL_FILE &&
+                    pollset->p->query_set[i].desc.f == pollset->wakeup_pipe[0]) {
+                        apr_pollset_drain_wakeup_pipe(pollset);
                         rv = APR_EINTR;
                 }
                 else {
-                    pollset->result_set[j] = pollset->query_set[i];
-                    pollset->result_set[j].rtnevents =
-                        get_revent(pollset->pollset[i].revents);
+                    pollset->p->result_set[j] = pollset->p->query_set[i];
+                    pollset->p->result_set[j].rtnevents =
+                        get_revent(pollset->p->pollset[i].revents);
                     j++;
                 }
             }
@@ -359,45 +270,134 @@
             rv = APR_SUCCESS;
     }
     if (descriptors && (*num))
-        *descriptors = pollset->result_set;
+        *descriptors = pollset->p->result_set;
     return rv;
 }
 
-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;
+static apr_pollset_provider_t impl = {
+    impl_pollset_create,
+    impl_pollset_add,
+    impl_pollset_remove,
+    impl_pollset_poll,
+    NULL,
+    "pool"
+};
+
+apr_pollset_provider_t *apr_pollset_provider_poll = &impl;
+
+/* Poll method pollcb.
+ * This is probably usable only for WIN32 having WSAPoll
+ */
+static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb,
+                                       apr_uint32_t size,
+                                       apr_pool_t *p,
+                                       apr_uint32_t flags)
+{
+    pollcb->fd = -1;
+    pollcb->pollset.ps = apr_palloc(p, size * sizeof(struct pollfd));
+    pollcb->copyset = apr_palloc(p, size * sizeof(apr_pollfd_t *));
+
+    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)
+static apr_status_t impl_pollcb_add(apr_pollcb_t *pollcb,
+                                    apr_pollfd_t *descriptor)
 {
-    return APR_ENOTIMPL;
+    if (pollcb->nelts == pollcb->nalloc) {
+        return APR_ENOMEM;
+    }
+
+    if (descriptor->desc_type == APR_POLL_SOCKET) {
+        pollcb->pollset.ps[pollcb->nelts].fd = descriptor->desc.s->socketdes;
+    }
+    else {
+        pollcb->pollset.ps[pollcb->nelts].fd = descriptor->desc.f->filedes;
+    }
+
+    pollcb->pollset.ps[pollcb->nelts].events =
+        get_event(descriptor->reqevents);
+    pollcb->copyset[pollcb->nelts] = descriptor;
+    pollcb->nelts++;
+    
+    return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb,
-                                         apr_pollfd_t *descriptor)
+static apr_status_t impl_pollcb_remove(apr_pollcb_t *pollcb,
+                                       apr_pollfd_t *descriptor)
 {
-    return APR_ENOTIMPL;
+    int fd;
+    apr_uint32_t i;
+
+    if (descriptor->desc_type == APR_POLL_SOCKET)
+        fd = descriptor->desc.s->socketdes;
+    else
+        fd = descriptor->desc.f->filedes;
+
+    for (i = 0; i < pollcb->nelts; i++) {
+        if (descriptor->desc.s == pollcb->copyset[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 = pollcb->nelts;
+            pollcb->nelts--;
+            for (i++; i < old_nelts; i++) {
+                if (descriptor->desc.s == pollcb->copyset[i]->desc.s) {
+                    pollcb->nelts--;
+                }
+                else {
+                    pollcb->pollset.ps[dst] = pollcb->pollset.ps[i];
+                    pollcb->copyset[dst] = pollcb->copyset[i];
+                    dst++;
+                }
+            }
+            return APR_SUCCESS;
+        }
+    }
+
+    return APR_NOTFOUND;
 }
 
-APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb,
-                                            apr_pollfd_t *descriptor)
+static apr_status_t impl_pollcb_poll(apr_pollcb_t *pollcb,
+                                     apr_interval_time_t timeout,
+                                     apr_pollcb_cb_t func,
+                                     void *baton)
 {
-    return APR_ENOTIMPL;
+    int ret;
+    apr_status_t rv = APR_SUCCESS;
+    apr_uint32_t i, j;
+
+    if (timeout > 0) {
+        timeout /= 1000;
+    }
+    ret = poll(pollcb->pollset.ps, pollcb->nelts, timeout);
+    if (ret < 0) {
+        return apr_get_netos_error();
+    }
+    else if (ret == 0) {
+        return APR_TIMEUP;
+    }
+    else {
+        for (i = 0; i < pollcb->nelts; i++) {
+            if (pollcb->pollset.ps[i].revents != 0) {
+                apr_pollfd_t *pollfd = pollcb->copyset[i];
+                pollfd->rtnevents = get_revent(pollcb->pollset.ps[i].revents);                    
+                rv = func(baton, pollfd);
+                if (rv) {
+                    return rv;
+                }
+            }
+        }
+    }
+    return rv;
 }
 
+static apr_pollcb_provider_t impl_cb = {
+    impl_pollcb_create,
+    impl_pollcb_add,
+    impl_pollcb_remove,
+    impl_pollcb_poll,
+    "poll"
+};
 
-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 APR_ENOTIMPL;
-}
+apr_pollcb_provider_t *apr_pollcb_provider_poll = &impl_cb;
 
-#endif /* POLLSET_USES_POLL */
+#endif /* HAVE_POLL */

Modified: apr/apr/trunk/poll/unix/port.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/poll/unix/port.c?rev=744095&r1=744094&r2=744095&view=diff
==============================================================================
--- apr/apr/trunk/poll/unix/port.c (original)
+++ apr/apr/trunk/poll/unix/port.c Fri Feb 13 12:24:00 2009
@@ -14,10 +14,16 @@
  * limitations under the License.
  */
 
-#include "apr_arch_poll_private.h"
+#include "apr.h"
+#include "apr_poll.h"
+#include "apr_time.h"
+#include "apr_portable.h"
 #include "apr_atomic.h"
+#include "apr_arch_file_io.h"
+#include "apr_arch_networkio.h"
+#include "apr_arch_poll_private.h"
 
-#ifdef POLLSET_USES_PORT
+#if defined(HAVE_PORT_CREATE)
 
 static apr_int16_t get_event(apr_int16_t event)
 {
@@ -60,17 +66,11 @@
 }
 
 
-struct apr_pollset_t
+struct apr_pollset_private_t
 {
-    apr_pool_t *pool;
-    apr_uint32_t nelts;
-    apr_uint32_t nalloc;
     int port_fd;
     port_event_t *port_set;
     apr_pollfd_t *result_set;
-    apr_uint32_t flags;
-    /* Pipe descriptors used for wakeup */
-    apr_file_t *wakeup_pipe[2];
 #if APR_HAS_THREADS
     /* A thread mutex to protect operations on the rings */
     apr_thread_mutex_t *ring_lock;
@@ -87,79 +87,30 @@
     volatile apr_uint32_t waiting;
 };
 
-static apr_status_t backend_cleanup(void *p_)
+static apr_status_t impl_pollset_cleanup(apr_pollset_t *pollset)
 {
-    apr_pollset_t *pollset = (apr_pollset_t *) p_;
-    close(pollset->port_fd);
-    if (pollset->flags & APR_POLLSET_WAKEABLE) {
-        /* Close both sides of the wakeup pipe */
-        if (pollset->wakeup_pipe[0]) {
-            apr_file_close(pollset->wakeup_pipe[0]);
-            pollset->wakeup_pipe[0] = NULL;
-        }
-        if (pollset->wakeup_pipe[1]) {
-            apr_file_close(pollset->wakeup_pipe[1]);
-            pollset->wakeup_pipe[1] = NULL;
-        }
-    }
+    close(pollset->p->port_fd);
     return APR_SUCCESS;
 }
 
-/* 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];
-    /* Add the pipe to the pollset
-     */
-    return apr_pollset_add(pollset, &fd);
-}
-
-/* Read and discard what's ever in the wakeup pipe.
- */
-static void 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;
-    }
-}
-
-APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
+static apr_status_t impl_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));
+    pollset->p = apr_palloc(p, sizeof(apr_pollset_private_t));
 #if APR_HAS_THREADS
     if (flags & APR_POLLSET_THREADSAFE &&
-        ((rv = apr_thread_mutex_create(&(*pollset)->ring_lock,
+        ((rv = apr_thread_mutex_create(&pollset->p->ring_lock,
                                        APR_THREAD_MUTEX_DEFAULT,
                                        p)) != APR_SUCCESS)) {
-        *pollset = NULL;
+        pollset->p = NULL;
         return rv;
     }
 #else
     if (flags & APR_POLLSET_THREADSAFE) {
-        *pollset = NULL;
+        pollset->p = NULL;
         return APR_ENOTIMPL;
     }
 #endif
@@ -167,48 +118,29 @@
         /* Add room for wakeup descriptor */
         size++;
     }
-    (*pollset)->waiting = 0;
-    (*pollset)->nelts = 0;
-    (*pollset)->nalloc = size;
-    (*pollset)->flags = flags;
-    (*pollset)->pool = p;
+    pollset->p->waiting = 0;
 
-    (*pollset)->port_set = apr_palloc(p, size * sizeof(port_event_t));
+    pollset->p->port_set = apr_palloc(p, size * sizeof(port_event_t));
 
-    (*pollset)->port_fd = port_create();
+    pollset->p->port_fd = port_create();
 
-    if ((*pollset)->port_fd < 0) {
+    if (pollset->p->port_fd < 0) {
+        pollset->p = NULL;
         return APR_ENOMEM;
     }
 
-    (*pollset)->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
+    pollset->p->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
 
-    APR_RING_INIT(&(*pollset)->query_ring, pfd_elem_t, link);
-    APR_RING_INIT(&(*pollset)->add_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);
-
-    if (flags & APR_POLLSET_WAKEABLE) {
-        /* Create wakeup pipe */
-        if ((rv = create_wakeup_pipe(*pollset)) != APR_SUCCESS) {
-            close((*pollset)->port_fd);
-            *pollset = NULL;
-            return rv;
-        }
-    }
-    apr_pool_cleanup_register(p, (void *) (*pollset), backend_cleanup,
-                              apr_pool_cleanup_null);
+    APR_RING_INIT(&pollset->p->query_ring, pfd_elem_t, link);
+    APR_RING_INIT(&pollset->p->add_ring, pfd_elem_t, link);
+    APR_RING_INIT(&pollset->p->free_ring, pfd_elem_t, link);
+    APR_RING_INIT(&pollset->p->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)
+static apr_status_t impl_pollset_add(apr_pollset_t *pollset,
+                                     const apr_pollfd_t *descriptor)
 {
     apr_os_sock_t fd;
     pfd_elem_t *elem;
@@ -217,8 +149,8 @@
 
     pollset_lock_rings();
 
-    if (!APR_RING_EMPTY(&(pollset->free_ring), pfd_elem_t, link)) {
-        elem = APR_RING_FIRST(&(pollset->free_ring));
+    if (!APR_RING_EMPTY(&(pollset->p->free_ring), pfd_elem_t, link)) {
+        elem = APR_RING_FIRST(&(pollset->p->free_ring));
         APR_RING_REMOVE(elem, link);
     }
     else {
@@ -234,22 +166,22 @@
         fd = descriptor->desc.f->filedes;
     }
 
-    if (apr_atomic_read32(&pollset->waiting)) {
-        res = port_associate(pollset->port_fd, PORT_SOURCE_FD, fd, 
+    if (apr_atomic_read32(&pollset->p->waiting)) {
+        res = port_associate(pollset->p->port_fd, PORT_SOURCE_FD, fd, 
                              get_event(descriptor->reqevents), (void *)elem);
 
         if (res < 0) {
             rv = APR_ENOMEM;
-            APR_RING_INSERT_TAIL(&(pollset->free_ring), elem, pfd_elem_t, link);
+            APR_RING_INSERT_TAIL(&(pollset->p->free_ring), elem, pfd_elem_t, link);
         }
         else {
             pollset->nelts++;
-            APR_RING_INSERT_TAIL(&(pollset->query_ring), elem, pfd_elem_t, link);
+            APR_RING_INSERT_TAIL(&(pollset->p->query_ring), elem, pfd_elem_t, link);
         }
     } 
     else {
         pollset->nelts++;
-        APR_RING_INSERT_TAIL(&(pollset->add_ring), elem, pfd_elem_t, link);
+        APR_RING_INSERT_TAIL(&(pollset->p->add_ring), elem, pfd_elem_t, link);
     }
 
     pollset_unlock_rings();
@@ -257,8 +189,8 @@
     return rv;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
-                                             const apr_pollfd_t *descriptor)
+static apr_status_t impl_pollset_remove(apr_pollset_t *pollset,
+                                        const apr_pollfd_t *descriptor)
 {
     apr_os_sock_t fd;
     pfd_elem_t *ep;
@@ -275,22 +207,22 @@
         fd = descriptor->desc.f->filedes;
     }
 
-    res = port_dissociate(pollset->port_fd, PORT_SOURCE_FD, fd);
+    res = port_dissociate(pollset->p->port_fd, PORT_SOURCE_FD, fd);
 
     if (res < 0) {
         err = errno;
         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),
+    if (!APR_RING_EMPTY(&(pollset->p->query_ring), pfd_elem_t, link)) {
+        for (ep = APR_RING_FIRST(&(pollset->p->query_ring));
+             ep != APR_RING_SENTINEL(&(pollset->p->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),
+                APR_RING_INSERT_TAIL(&(pollset->p->dead_ring),
                                      ep, pfd_elem_t, link);
                 if (ENOENT == err) {
                     rv = APR_SUCCESS;
@@ -300,15 +232,15 @@
         }
     }
 
-    if (!APR_RING_EMPTY(&(pollset->add_ring), pfd_elem_t, link)) {
-        for (ep = APR_RING_FIRST(&(pollset->add_ring));
-             ep != APR_RING_SENTINEL(&(pollset->add_ring),
+    if (!APR_RING_EMPTY(&(pollset->p->add_ring), pfd_elem_t, link)) {
+        for (ep = APR_RING_FIRST(&(pollset->p->add_ring));
+             ep != APR_RING_SENTINEL(&(pollset->p->add_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),
+                APR_RING_INSERT_TAIL(&(pollset->p->dead_ring),
                                      ep, pfd_elem_t, link);
                 if (ENOENT == err) {
                     rv = APR_SUCCESS;
@@ -323,10 +255,10 @@
     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)
+static apr_status_t impl_pollset_poll(apr_pollset_t *pollset,
+                                      apr_interval_time_t timeout,
+                                      apr_int32_t *num,
+                                      const apr_pollfd_t **descriptors)
 {
     apr_os_sock_t fd;
     int ret, i, j;
@@ -349,10 +281,10 @@
 
     pollset_lock_rings();
 
-    apr_atomic_inc32(&pollset->waiting);
+    apr_atomic_inc32(&pollset->p->waiting);
 
-    while (!APR_RING_EMPTY(&(pollset->add_ring), pfd_elem_t, link)) {
-        ep = APR_RING_FIRST(&(pollset->add_ring));
+    while (!APR_RING_EMPTY(&(pollset->p->add_ring), pfd_elem_t, link)) {
+        ep = APR_RING_FIRST(&(pollset->p->add_ring));
         APR_RING_REMOVE(ep, link);
 
         if (ep->pfd.desc_type == APR_POLL_SOCKET) {
@@ -362,21 +294,21 @@
             fd = ep->pfd.desc.f->filedes;
         }
 
-        port_associate(pollset->port_fd, PORT_SOURCE_FD, 
+        port_associate(pollset->p->port_fd, PORT_SOURCE_FD, 
                            fd, get_event(ep->pfd.reqevents), ep);
 
-        APR_RING_INSERT_TAIL(&(pollset->query_ring), ep, pfd_elem_t, link);
+        APR_RING_INSERT_TAIL(&(pollset->p->query_ring), ep, pfd_elem_t, link);
 
     }
 
     pollset_unlock_rings();
 
-    ret = port_getn(pollset->port_fd, pollset->port_set, pollset->nalloc,
+    ret = port_getn(pollset->p->port_fd, pollset->p->port_set, pollset->nalloc,
                     &nget, tvptr);
 
     /* decrease the waiting ASAP to reduce the window for calling 
        port_associate within apr_pollset_add() */
-    apr_atomic_dec32(&pollset->waiting);
+    apr_atomic_dec32(&pollset->p->waiting);
     (*num) = nget;
 
     if (ret == -1) {
@@ -399,22 +331,22 @@
         pollset_lock_rings();
 
         for (i = 0, j = 0; i < nget; i++) {
-            fp = (((pfd_elem_t*)(pollset->port_set[i].portev_user))->pfd);
+            fp = (((pfd_elem_t*)(pollset->p->port_set[i].portev_user))->pfd);
             if ((pollset->flags & APR_POLLSET_WAKEABLE) &&
                 fp.desc_type == APR_POLL_FILE &&
                 fp.desc.f == pollset->wakeup_pipe[0]) {
-                drain_wakeup_pipe(pollset);
+                apr_pollset_drain_wakeup_pipe(pollset);
                 rv = APR_EINTR;
             }
             else {
-                pollset->result_set[j] = fp;            
-                pollset->result_set[j].rtnevents =
-                    get_revent(pollset->port_set[i].portev_events);
+                pollset->p->result_set[j] = fp;            
+                pollset->p->result_set[j].rtnevents =
+                    get_revent(pollset->p->port_set[i].portev_events);
 
-                APR_RING_REMOVE((pfd_elem_t*)pollset->port_set[i].portev_user,
+                APR_RING_REMOVE((pfd_elem_t*)pollset->p->port_set[i].portev_user,
                                 link);
-                APR_RING_INSERT_TAIL(&(pollset->add_ring), 
-                                (pfd_elem_t*)pollset->port_set[i].portev_user,
+                APR_RING_INSERT_TAIL(&(pollset->p->add_ring), 
+                                (pfd_elem_t*)pollset->p->port_set[i].portev_user,
                                 pfd_elem_t, link);
                 j++;
             }
@@ -423,7 +355,7 @@
         if ((*num) = j)
             rv = APR_SUCCESS;
         if (descriptors) {
-            *descriptors = pollset->result_set;
+            *descriptors = pollset->p->result_set;
         }
     }
 
@@ -431,61 +363,52 @@
     pollset_lock_rings();
 
     /* Shift all PFDs in the Dead Ring to be Free Ring */
-    APR_RING_CONCAT(&(pollset->free_ring), &(pollset->dead_ring), pfd_elem_t, link);
+    APR_RING_CONCAT(&(pollset->p->free_ring), &(pollset->p->dead_ring), pfd_elem_t, link);
 
     pollset_unlock_rings();
 
     return rv;
 }
 
-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;
-}
-
-struct apr_pollcb_t {
-    apr_pool_t *pool;
-    apr_uint32_t nalloc;
-    port_event_t *port_set;
-    int port_fd;
+static apr_pollset_provider_t impl = {
+    impl_pollset_create,
+    impl_pollset_add,
+    impl_pollset_remove,
+    impl_pollset_poll,
+    impl_pollset_cleanup,
+    "port"
 };
 
+apr_pollset_provider_t *apr_pollset_provider_port = &impl;
+
 static apr_status_t cb_cleanup(void *p_)
 {
     apr_pollcb_t *pollcb = (apr_pollcb_t *) p_;
-    close(pollcb->port_fd);
+    close(pollcb->fd);
     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)
+static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb,
+                                       apr_uint32_t size,
+                                       apr_pool_t *p,
+                                       apr_uint32_t flags)
 {
     int fd;
 
     fd = port_create();
 
     if (fd < 0) {
-        *pollcb = NULL;
         return apr_get_netos_error();
     }
 
-    *pollcb = apr_palloc(p, sizeof(**pollcb));
-    (*pollcb)->nalloc = size;
-    (*pollcb)->pool = p;
-    (*pollcb)->port_fd = fd;
-    (*pollcb)->port_set = apr_palloc(p, size * sizeof(port_event_t));
-    apr_pool_cleanup_register(p, *pollcb, cb_cleanup, cb_cleanup);
+    pollcb->pollset.port = apr_palloc(p, size * sizeof(port_event_t));
+    apr_pool_cleanup_register(p, pollcb, cb_cleanup, cb_cleanup);
 
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb,
-                                         apr_pollfd_t *descriptor)
+static apr_status_t impl_pollcb_add(apr_pollcb_t *pollcb,
+                                    apr_pollfd_t *descriptor)
 {
     int ret, fd;
 
@@ -496,7 +419,7 @@
         fd = descriptor->desc.f->filedes;
     }
 
-    ret = port_associate(pollcb->port_fd, PORT_SOURCE_FD, fd,
+    ret = port_associate(pollcb->fd, PORT_SOURCE_FD, fd,
                          get_event(descriptor->reqevents), descriptor);
 
     if (ret == -1) {
@@ -506,8 +429,8 @@
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb,
-                                            apr_pollfd_t *descriptor)
+static apr_status_t impl_pollcb_remove(apr_pollcb_t *pollcb,
+                                       apr_pollfd_t *descriptor)
 {
     int fd, ret;
 
@@ -518,7 +441,7 @@
         fd = descriptor->desc.f->filedes;
     }
 
-    ret = port_dissociate(pollcb->port_fd, PORT_SOURCE_FD, fd);
+    ret = port_dissociate(pollcb->fd, PORT_SOURCE_FD, fd);
 
     if (ret < 0) {
         return APR_NOTFOUND;
@@ -527,10 +450,10 @@
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb,
-                                          apr_interval_time_t timeout,
-                                          apr_pollcb_cb_t func,
-                                          void *baton)
+static apr_status_t impl_pollcb_poll(apr_pollcb_t *pollcb,
+                                     apr_interval_time_t timeout,
+                                     apr_pollcb_cb_t func,
+                                     void *baton)
 {
     int ret;
     apr_pollfd_t *pollfd;
@@ -547,7 +470,7 @@
         tvptr = &tv;
     }
 
-    ret = port_getn(pollcb->port_fd, pollcb->port_set, pollcb->nalloc,
+    ret = port_getn(pollcb->fd, pollcb->pollset.port, pollcb->nalloc,
                     &nget, tvptr);
 
     if (ret == -1) {
@@ -563,8 +486,8 @@
     }
     else {
         for (i = 0; i < nget; i++) {
-            pollfd = (apr_pollfd_t *)(pollcb->port_set[i].portev_user);
-            pollfd->rtnevents = get_revent(pollcb->port_set[i].portev_events);
+            pollfd = (apr_pollfd_t *)(pollcb->pollset.port[i].portev_user);
+            pollfd->rtnevents = get_revent(pollcb->pollset.port[i].portev_events);
 
             rv = func(baton, pollfd);
             if (rv) {
@@ -577,4 +500,14 @@
     return rv;
 }
 
-#endif /* POLLSET_USES_PORT */
+static apr_pollcb_provider_t impl_cb = {
+    impl_pollcb_create,
+    impl_pollcb_add,
+    impl_pollcb_remove,
+    impl_pollcb_poll,
+    "port"
+};
+
+apr_pollcb_provider_t *apr_pollcb_provider_port = &impl_cb;
+
+#endif /* HAVE_PORT_CREATE */



Re: svn commit: r744095 [1/2] - in /apr/apr/trunk: ./ include/ include/arch/unix/ poll/os2/ poll/unix/

Posted by Mladen Turk <mt...@apache.org>.
Ruediger Pluem wrote:
> 
>> +    impl_pollset_cleanup,
>> +    "epool"
> 
> Guess this should be epoll instead of epool above :-).
>

Right :)

>> +static apr_status_t impl_pollcb_remove(apr_pollcb_t *pollcb,
>> +                                       apr_pollfd_t *descriptor)
>>  {
>> -    return APR_ENOTIMPL;
>> +    int fd;
>> +    apr_uint32_t i;
>> +
>> +    if (descriptor->desc_type == APR_POLL_SOCKET)
>> +        fd = descriptor->desc.s->socketdes;
>> +    else
>> +        fd = descriptor->desc.f->filedes;
>> +
>> +    for (i = 0; i < pollcb->nelts; i++) {
>> +        if (descriptor->desc.s == pollcb->copyset[i]->desc.s) {
>> +            /* Found an instance of the fd: remove this and any other copies */
> 
> I don't grok this algorithm. Why do we determine the fd above and work only with
> socket fd's in the loop? We should either compare the descriptors itself or if
> this is unreliable we need to check the fd against the correct counterpart.
>

With pollcb checking descriptors is by design reliable.
I've removed the dormant code.

>> +    pollcb->pollset.port = apr_palloc(p, size * sizeof(port_event_t));
>> +    apr_pool_cleanup_register(p, pollcb, cb_cleanup, cb_cleanup);
> 
> Why don't you save fd to pollcb->fd?
>

Makes sense, I'll do that.


Thanks
-- 
^(TM)

Re: svn commit: r744095 [1/2] - in /apr/apr/trunk: ./ include/ include/arch/unix/ poll/os2/ poll/unix/

Posted by Ruediger Pluem <rp...@apache.org>.

On 02/13/2009 01:24 PM, mturk@apache.org wrote:
> Author: mturk
> Date: Fri Feb 13 12:24:00 2009
> New Revision: 744095
> 
> URL: http://svn.apache.org/viewvc?rev=744095&view=rev
> Log:
> Implement providers for apr_pollset and apr_pollcb
> 
> Modified:
>     apr/apr/trunk/CHANGES
>     apr/apr/trunk/NWGNUmakefile
>     apr/apr/trunk/apr.dsp
>     apr/apr/trunk/include/apr_poll.h
>     apr/apr/trunk/include/arch/unix/apr_arch_poll_private.h
>     apr/apr/trunk/libapr.dsp
>     apr/apr/trunk/poll/os2/pollset.c
>     apr/apr/trunk/poll/unix/epoll.c
>     apr/apr/trunk/poll/unix/kqueue.c
>     apr/apr/trunk/poll/unix/poll.c
>     apr/apr/trunk/poll/unix/port.c
>     apr/apr/trunk/poll/unix/select.c
> 

> Modified: apr/apr/trunk/poll/unix/epoll.c
> URL: http://svn.apache.org/viewvc/apr/apr/trunk/poll/unix/epoll.c?rev=744095&r1=744094&r2=744095&view=diff
> ==============================================================================
> --- apr/apr/trunk/poll/unix/epoll.c (original)
> +++ apr/apr/trunk/poll/unix/epoll.c Fri Feb 13 12:24:00 2009

> @@ -384,54 +318,46 @@
>      return rv;
>  }
>  
> -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;
> -}
> -
> -struct apr_pollcb_t {
> -    apr_pool_t *pool;
> -    apr_uint32_t nalloc;
> -    struct epoll_event *pollset;
> -    int epoll_fd;
> +static apr_pollset_provider_t impl = {
> +    impl_pollset_create,
> +    impl_pollset_add,
> +    impl_pollset_remove,
> +    impl_pollset_poll,
> +    impl_pollset_cleanup,
> +    "epool"

Guess this should be epoll instead of epool above :-).

>  };
>  

> Modified: apr/apr/trunk/poll/unix/poll.c
> URL: http://svn.apache.org/viewvc/apr/apr/trunk/poll/unix/poll.c?rev=744095&r1=744094&r2=744095&view=diff
> ==============================================================================
> --- apr/apr/trunk/poll/unix/poll.c (original)
> +++ apr/apr/trunk/poll/unix/poll.c Fri Feb 13 12:24:00 2009
             }
> @@ -359,45 +270,134 @@
>              rv = APR_SUCCESS;
>      }
>      if (descriptors && (*num))
> -        *descriptors = pollset->result_set;
> +        *descriptors = pollset->p->result_set;
>      return rv;
>  }
>  
> -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;
> +static apr_pollset_provider_t impl = {
> +    impl_pollset_create,
> +    impl_pollset_add,
> +    impl_pollset_remove,
> +    impl_pollset_poll,
> +    NULL,
> +    "pool"

Guess this should be poll instead of pool above :-).

> +};
> +
> +apr_pollset_provider_t *apr_pollset_provider_poll = &impl;
> +
> +/* Poll method pollcb.
> + * This is probably usable only for WIN32 having WSAPoll
> + */
> +static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb,
> +                                       apr_uint32_t size,
> +                                       apr_pool_t *p,
> +                                       apr_uint32_t flags)
> +{
> +    pollcb->fd = -1;
> +    pollcb->pollset.ps = apr_palloc(p, size * sizeof(struct pollfd));
> +    pollcb->copyset = apr_palloc(p, size * sizeof(apr_pollfd_t *));
> +
> +    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)
> +static apr_status_t impl_pollcb_add(apr_pollcb_t *pollcb,
> +                                    apr_pollfd_t *descriptor)
>  {
> -    return APR_ENOTIMPL;
> +    if (pollcb->nelts == pollcb->nalloc) {
> +        return APR_ENOMEM;
> +    }
> +
> +    if (descriptor->desc_type == APR_POLL_SOCKET) {
> +        pollcb->pollset.ps[pollcb->nelts].fd = descriptor->desc.s->socketdes;
> +    }
> +    else {
> +        pollcb->pollset.ps[pollcb->nelts].fd = descriptor->desc.f->filedes;
> +    }
> +
> +    pollcb->pollset.ps[pollcb->nelts].events =
> +        get_event(descriptor->reqevents);
> +    pollcb->copyset[pollcb->nelts] = descriptor;
> +    pollcb->nelts++;
> +    
> +    return APR_SUCCESS;
>  }
>  
> -APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb,
> -                                         apr_pollfd_t *descriptor)
> +static apr_status_t impl_pollcb_remove(apr_pollcb_t *pollcb,
> +                                       apr_pollfd_t *descriptor)
>  {
> -    return APR_ENOTIMPL;
> +    int fd;
> +    apr_uint32_t i;
> +
> +    if (descriptor->desc_type == APR_POLL_SOCKET)
> +        fd = descriptor->desc.s->socketdes;
> +    else
> +        fd = descriptor->desc.f->filedes;
> +
> +    for (i = 0; i < pollcb->nelts; i++) {
> +        if (descriptor->desc.s == pollcb->copyset[i]->desc.s) {
> +            /* Found an instance of the fd: remove this and any other copies */

I don't grok this algorithm. Why do we determine the fd above and work only with
socket fd's in the loop? We should either compare the descriptors itself or if
this is unreliable we need to check the fd against the correct counterpart.

> +            apr_uint32_t dst = i;
> +            apr_uint32_t old_nelts = pollcb->nelts;
> +            pollcb->nelts--;
> +            for (i++; i < old_nelts; i++) {
> +                if (descriptor->desc.s == pollcb->copyset[i]->desc.s) {
> +                    pollcb->nelts--;
> +                }
> +                else {
> +                    pollcb->pollset.ps[dst] = pollcb->pollset.ps[i];
> +                    pollcb->copyset[dst] = pollcb->copyset[i];
> +                    dst++;
> +                }
> +            }
> +            return APR_SUCCESS;
> +        }
> +    }
> +
> +    return APR_NOTFOUND;
>  }
>  

> Modified: apr/apr/trunk/poll/unix/port.c
> URL: http://svn.apache.org/viewvc/apr/apr/trunk/poll/unix/port.c?rev=744095&r1=744094&r2=744095&view=diff
> ==============================================================================
> --- apr/apr/trunk/poll/unix/port.c (original)
> +++ apr/apr/trunk/poll/unix/port.c Fri Feb 13 12:24:00 2009

> @@ -431,61 +363,52 @@
>      pollset_lock_rings();
>  
>      /* Shift all PFDs in the Dead Ring to be Free Ring */
> -    APR_RING_CONCAT(&(pollset->free_ring), &(pollset->dead_ring), pfd_elem_t, link);
> +    APR_RING_CONCAT(&(pollset->p->free_ring), &(pollset->p->dead_ring), pfd_elem_t, link);
>  
>      pollset_unlock_rings();
>  
>      return rv;
>  }
>  
> -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;
> -}
> -
> -struct apr_pollcb_t {
> -    apr_pool_t *pool;
> -    apr_uint32_t nalloc;
> -    port_event_t *port_set;
> -    int port_fd;
> +static apr_pollset_provider_t impl = {
> +    impl_pollset_create,
> +    impl_pollset_add,
> +    impl_pollset_remove,
> +    impl_pollset_poll,
> +    impl_pollset_cleanup,
> +    "port"
>  };
>  
> +apr_pollset_provider_t *apr_pollset_provider_port = &impl;
> +
>  static apr_status_t cb_cleanup(void *p_)
>  {
>      apr_pollcb_t *pollcb = (apr_pollcb_t *) p_;
> -    close(pollcb->port_fd);
> +    close(pollcb->fd);
>      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)
> +static apr_status_t impl_pollcb_create(apr_pollcb_t *pollcb,
> +                                       apr_uint32_t size,
> +                                       apr_pool_t *p,
> +                                       apr_uint32_t flags)
>  {
>      int fd;
>  
>      fd = port_create();
>  
>      if (fd < 0) {
> -        *pollcb = NULL;
>          return apr_get_netos_error();
>      }
>  
> -    *pollcb = apr_palloc(p, sizeof(**pollcb));
> -    (*pollcb)->nalloc = size;
> -    (*pollcb)->pool = p;
> -    (*pollcb)->port_fd = fd;
> -    (*pollcb)->port_set = apr_palloc(p, size * sizeof(port_event_t));
> -    apr_pool_cleanup_register(p, *pollcb, cb_cleanup, cb_cleanup);
> +    pollcb->pollset.port = apr_palloc(p, size * sizeof(port_event_t));
> +    apr_pool_cleanup_register(p, pollcb, cb_cleanup, cb_cleanup);

Why don't you save fd to pollcb->fd?

>  
>      return APR_SUCCESS;
>  }
>  
> -APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb,
> -                                         apr_pollfd_t *descriptor)
> +static apr_status_t impl_pollcb_add(apr_pollcb_t *pollcb,
> +                                    apr_pollfd_t *descriptor)
>  {
>      int ret, fd;
>  

Regards

RĂ¼diger