Hi,

Currently, apr chooses whether to use epoll, kqueue, port, select or
poll at build-time.  This works quite well if your apr library is only
used on hosts with the same capabilities as the one you built on.
However, if you build on Linux 2.6 and try to use the binaries on
Linux 2.4, they don't work (due to the epoll interface not existing on
2.4).  http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=392373 is an
example bug report which shows the problem

To work around this, I have written a patch that does the selection at
runtime.  It has a small performance overhead (a function call and a
switch/case statement).  The alternative is to use function pointers
(initialised from apr_initialize), but this will break the ABI as well
as probably not being faster than a wrapper function.

I have no experience with kqueue and port-based systems, so this patch
may or may not work on platforms using those interfaces.  I have tried
to write sensible implementations, but they are untested and probably
require some changes.  I have not checked whether this is applicable
to OS/2 as well, but I don't think it is.

http://err.no/patches/apr_runtime_detection_poll.diff is a diff
against current SVN.  The same patch is attached.

Feedback, positive or negative, is appreciated.
-- 
Tollef Fog Heen                                                        ,''`.
UNIX is user friendly, it's just picky about who its friends are      : :' :
                                                                      `. `' 
                                                                        `-  
Index: include/arch/unix/apr_arch_poll_private.h
===================================================================
--- include/arch/unix/apr_arch_poll_private.h	(revisjon 463892)
+++ include/arch/unix/apr_arch_poll_private.h	(arbeidskopi)
@@ -52,27 +52,80 @@
 #define HAS_PIPES(dt) (dt == APR_POLL_FILE) ? 1 : 0
 #endif
 
-/* Choose the best method platform specific to use in apr_pollset */
-#ifdef HAVE_KQUEUE
-#define POLLSET_USES_KQUEUE
-#elif defined(HAVE_PORT_CREATE)
-#define POLLSET_USES_PORT
-#elif defined(HAVE_EPOLL)
-#define POLLSET_USES_EPOLL
-#elif defined(HAVE_POLL)
-#define POLLSET_USES_POLL
-#else
-#define POLLSET_USES_SELECT
+#ifdef HAVE_EPOLL
+APR_DECLARE(apr_status_t) apr_epoll_pollset_create(apr_pollset_t **_pollset,
+                                                   apr_uint32_t size,
+                                                   apr_pool_t *p,
+                                                   apr_uint32_t flags);
+APR_DECLARE(apr_status_t) apr_epoll_pollset_destroy(apr_pollset_t *_pollset);
+APR_DECLARE(apr_status_t) apr_epoll_pollset_add(apr_pollset_t *_pollset,
+                                                const apr_pollfd_t *descriptor);
+
+APR_DECLARE(apr_status_t) apr_epoll_pollset_remove(apr_pollset_t *_pollset,
+                                                   const apr_pollfd_t *descriptor);
+APR_DECLARE(apr_status_t) apr_epoll_pollset_poll(apr_pollset_t *_pollset,
+                                                 apr_interval_time_t timeout,
+                                                 apr_int32_t *num,
+                                                 const apr_pollfd_t **descriptors);
+
 #endif
 
 #ifdef HAVE_POLL
-#define POLL_USES_POLL
-#else
-#define POLL_USES_SELECT
+APR_DECLARE(apr_status_t) apr_poll_poll(apr_pollfd_t *aprset, apr_int32_t num,
+                                        apr_int32_t *nsds, 
+                                        apr_interval_time_t timeout);
+APR_DECLARE(apr_status_t) apr_poll_pollset_create(apr_pollset_t **pollset_,
+                                                  apr_uint32_t size,
+                                                  apr_pool_t *p,
+                                                  apr_uint32_t flags);
+     APR_DECLARE(apr_status_t) apr_poll_pollset_destroy(apr_pollset_t *pollset);
+APR_DECLARE(apr_status_t) apr_poll_pollset_add(apr_pollset_t *pollset_,
+                                               const apr_pollfd_t *descriptor);
+APR_DECLARE(apr_status_t) apr_poll_pollset_remove(apr_pollset_t *pollset_,
+						  const apr_pollfd_t *descriptor);
+     APR_DECLARE(apr_status_t) apr_poll_pollset_poll(apr_pollset_t *pollset_,
+                                                     apr_interval_time_t timeout,
+                                                     apr_int32_t *num,
+                                                     const apr_pollfd_t **descriptors);
+
 #endif
 
-#if defined(POLLSET_USES_KQUEUE) || defined(POLLSET_USES_EPOLL) || defined(POLLSET_USES_PORT)
+#ifdef HAVE_KQUEUE
+APR_DECLARE(apr_status_t) apr_kqueue_pollset_create(apr_pollset_t **pollset_,
+						    apr_uint32_t size,
+						    apr_pool_t *p,
+						    apr_uint32_t flags);
+APR_DECLARE(apr_status_t) apr_kqueue_pollset_destroy(apr_pollset_t * pollset_);
+APR_DECLARE(apr_status_t) apr_kqueue_pollset_add(apr_pollset_t *pollset_,
+						 const apr_pollfd_t *descriptor);
+APR_DECLARE(apr_status_t) apr_kqueue_pollset_remove(apr_pollset_t *pollset_,
+						    const apr_pollfd_t *descriptor);
+APR_DECLARE(apr_status_t) apr_kqueue_pollset_poll(apr_pollset_t *pollset_,
+						  apr_interval_time_t timeout,
+						  apr_int32_t *num,
+						  const apr_pollfd_t **descriptors);
 
+#endif
+
+#ifdef HAVE_PORT_CREATE
+APR_DECLARE(apr_status_t) apr_port_pollset_create(apr_pollset_t **pollset_,
+						  apr_uint32_t size,
+						  apr_pool_t *p,
+						  apr_uint32_t flags);
+APR_DECLARE(apr_status_t) apr_port_pollset_destroy(apr_pollset_t * pollset_);
+APR_DECLARE(apr_status_t) apr_port_pollset_add(apr_pollset_t *pollset_,
+					       const apr_pollfd_t *descriptor);
+APR_DECLARE(apr_status_t) apr_port_pollset_remove(apr_pollset_t *pollset_,
+						  const apr_pollfd_t *descriptor);
+APR_DECLARE(apr_status_t) apr_port_pollset_poll(apr_pollset_t *pollset_,
+						apr_interval_time_t timeout,
+						apr_int32_t *num,
+						const apr_pollfd_t **descriptors);
+#endif
+
+
+#if defined(HAVE_KQUEUE) || defined(HAVE_EPOLL) || defined(HAVE_PORT_CREATE)
+
 #include "apr_ring.h"
 
 #if APR_HAS_THREADS
Index: misc/unix/start.c
===================================================================
--- misc/unix/start.c	(revisjon 463892)
+++ misc/unix/start.c	(arbeidskopi)
@@ -70,6 +70,8 @@
 
     apr_signal_init(pool);
 
+    apr_poll_init();
+
     return APR_SUCCESS;
 }
 
Index: poll/unix/kqueue.c
===================================================================
--- poll/unix/kqueue.c	(revisjon 463892)
+++ poll/unix/kqueue.c	(arbeidskopi)
@@ -16,7 +16,7 @@
 
 #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,7 +34,7 @@
     return rv;
 }
 
-struct apr_pollset_t
+struct apr_kqueue_pollset_t
 {
     apr_pool_t *pool;
     apr_uint32_t nelts;
@@ -57,6 +57,8 @@
     APR_RING_HEAD(pfd_dead_ring_t, pfd_elem_t) dead_ring;
 };
 
+typedef struct apr_kqueue_pollset_t apr_kqueue_pollset_t;
+
 static apr_status_t backend_cleanup(void *p_)
 {
     apr_pollset_t *pollset = (apr_pollset_t *) p_;
@@ -64,12 +66,13 @@
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
-                                             apr_uint32_t size,
-                                             apr_pool_t *p,
-                                             apr_uint32_t flags)
+APR_DECLARE(apr_status_t) apr_kqueue_pollset_create(apr_pollset_t **pollset_,
+						    apr_uint32_t size,
+						    apr_pool_t *p,
+						    apr_uint32_t flags)
 {
     apr_status_t rv = APR_SUCCESS;
+    apr_kqueue_pollset_t **pollset = (apr_kqueue_pollset_t **) pollset_;
     *pollset = apr_palloc(p, sizeof(**pollset));
 #if APR_HAS_THREADS
     if (flags & APR_POLLSET_THREADSAFE &&
@@ -113,17 +116,19 @@
     return rv;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t * pollset)
+APR_DECLARE(apr_status_t) apr_kqueue_pollset_destroy(apr_pollset_t * pollset_)
 {
+    apr_kqueue_pollset_t *pollset = (apr_kqueue_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,
+APR_DECLARE(apr_status_t) apr_kqueue_pollset_add(apr_pollset_t *pollset_,
                                           const apr_pollfd_t *descriptor)
 {
     apr_os_sock_t fd;
     pfd_elem_t *elem;
     apr_status_t rv = APR_SUCCESS;
+    apr_kqueue_pollset_t *pollset = (apr_kqueue_pollset_t *) pollset_;
 
     pollset_lock_rings();
 
@@ -175,12 +180,13 @@
     return rv;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
+APR_DECLARE(apr_status_t) apr_kqueue_pollset_remove(apr_pollset_t *pollset_,
                                              const apr_pollfd_t *descriptor)
 {
     pfd_elem_t *ep;
     apr_status_t rv = APR_SUCCESS;
     apr_os_sock_t fd;
+    apr_kqueue_pollset_t *pollset = (apr_kqueue_pollset_t *) pollset_;
 
     pollset_lock_rings();
 
@@ -229,7 +235,7 @@
     return rv;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset,
+APR_DECLARE(apr_status_t) apr_kqueue_pollset_poll(apr_pollset_t *pollset_,
                                            apr_interval_time_t timeout,
                                            apr_int32_t *num,
                                            const apr_pollfd_t **descriptors)
@@ -237,6 +243,7 @@
     int ret, i;
     struct timespec tv, *tvptr;
     apr_status_t rv = APR_SUCCESS;
+    apr_kqueue_pollset_t *pollset = (apr_kqueue_pollset_t *) pollset_;
 
     if (timeout < 0) {
         tvptr = NULL;
@@ -281,4 +288,4 @@
     return rv;
 }
 
-#endif /* POLLSET_USES_KQUEUE */
+#endif /* HAVE_KQUEUE */
Index: poll/unix/select.c
===================================================================
--- poll/unix/select.c	(revisjon 463892)
+++ poll/unix/select.c	(arbeidskopi)
@@ -27,11 +27,9 @@
 #include "apr_arch_file_io.h"
 #include "apr_arch_poll_private.h"
 
-#ifdef POLL_USES_SELECT
-
-APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, int num,
-                                   apr_int32_t *nsds,
-                                   apr_interval_time_t timeout)
+APR_DECLARE(apr_status_t) apr_select_poll(apr_pollfd_t *aprset, int num,
+                                          apr_int32_t *nsds,
+                                          apr_interval_time_t timeout)
 {
     fd_set readset, writeset, exceptset;
     int rv, i;
@@ -165,11 +163,7 @@
     return APR_SUCCESS;
 }
 
-#endif /* POLL_USES_SELECT */
-
-#ifdef POLLSET_USES_SELECT
-
-struct apr_pollset_t
+struct apr_select_pollset_t
 {
     apr_pool_t *pool;
 
@@ -184,11 +178,14 @@
 #endif
 };
 
-APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
-                                             apr_uint32_t size,
-                                             apr_pool_t *p,
-                                             apr_uint32_t flags)
+typedef struct apr_select_pollset_t apr_select_pollset_t;
+
+APR_DECLARE(apr_status_t) apr_select_pollset_create(apr_pollset_t **pollset_,
+						    apr_uint32_t size,
+						    apr_pool_t *p,
+						    apr_uint32_t flags)
 {
+    apr_select_pollset_t **pollset = (apr_select_pollset_t **) pollset_;
     if (flags & APR_POLLSET_THREADSAFE) {                
         *pollset = NULL;
         return APR_ENOTIMPL;
@@ -216,14 +213,15 @@
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t * pollset)
+APR_DECLARE(apr_status_t) apr_select_pollset_destroy(apr_pollset_t * pollset)
 {
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset,
-                                          const apr_pollfd_t *descriptor)
+APR_DECLARE(apr_status_t) apr_select_pollset_add(apr_pollset_t *pollset_,
+						 const apr_pollfd_t *descriptor)
 {
+    apr_select_pollset_t *pollset = (apr_select_pollset_t *) pollset_;
     apr_os_sock_t fd;
 
     if (pollset->nelts == pollset->nalloc) {
@@ -285,11 +283,12 @@
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t * pollset,
-                                             const apr_pollfd_t * descriptor)
+APR_DECLARE(apr_status_t) apr_select_pollset_remove(apr_pollset_t * pollset_,
+						    const apr_pollfd_t * descriptor)
 {
     apr_uint32_t i;
     apr_os_sock_t fd;
+    apr_select_pollset_t *pollset = (apr_select_pollset_t *) pollset_;
 
     if (descriptor->desc_type == APR_POLL_SOCKET) {
         fd = descriptor->desc.s->socketdes;
@@ -330,15 +329,16 @@
     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)
+APR_DECLARE(apr_status_t) apr_select_pollset_poll(apr_pollset_t *pollset_,
+                                                  apr_interval_time_t timeout,
+                                                  apr_int32_t *num,
+                                                  const apr_pollfd_t **descriptors)
 {
     int rv;
     apr_uint32_t i, j;
     struct timeval tv, *tvptr;
     fd_set readset, writeset, exceptset;
+    apr_select_pollset_t *pollset = (apr_select_pollset_t *) pollset_;
 
     if (timeout < 0) {
         tvptr = NULL;
@@ -406,4 +406,3 @@
     return APR_SUCCESS;
 }
 
-#endif /* POLLSET_USES_SELECT */
Index: poll/unix/port.c
===================================================================
--- poll/unix/port.c	(revisjon 463892)
+++ poll/unix/port.c	(arbeidskopi)
@@ -16,7 +16,7 @@
 
 #include "apr_arch_poll_private.h"
 
-#ifdef POLLSET_USES_PORT
+#ifdef HAVE_PORT_CREATE
 
 static apr_int16_t get_event(apr_int16_t event)
 {
@@ -59,7 +59,7 @@
 }
 
 
-struct apr_pollset_t
+struct apr_port_pollset_t
 {
     apr_pool_t *pool;
     apr_uint32_t nelts;
@@ -82,6 +82,8 @@
     APR_RING_HEAD(pfd_dead_ring_t, pfd_elem_t) dead_ring;
 };
 
+typedef struct apr_port_pollset_t apr_port_pollset_t;
+
 static apr_status_t backend_cleanup(void *p_)
 {
     apr_pollset_t *pollset = (apr_pollset_t *) p_;
@@ -89,12 +91,14 @@
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
+APR_DECLARE(apr_status_t) apr_port_pollset_create(apr_pollset_t **pollset_,
                                              apr_uint32_t size,
                                              apr_pool_t *p,
                                              apr_uint32_t flags)
 {
     apr_status_t rv = APR_SUCCESS;
+    apr_port_pollset_t **pollset = (apr_port_pollset_t **) pollset_;
+
     *pollset = apr_palloc(p, sizeof(**pollset));
 #if APR_HAS_THREADS
     if (flags & APR_POLLSET_THREADSAFE &&
@@ -136,18 +140,20 @@
     return rv;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset)
+APR_DECLARE(apr_status_t) apr_port_pollset_destroy(apr_pollset_t *pollset_)
 {
+    apr_port_pollset_t *pollset = (apr_port_pollset_t *) pollset_;
     return apr_pool_cleanup_run(pollset->pool, pollset, backend_cleanup);
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset,
-                                          const apr_pollfd_t *descriptor)
+APR_DECLARE(apr_status_t) apr_port_pollset_add(apr_pollset_t *pollset_,
+					       const apr_pollfd_t *descriptor)
 {
     apr_os_sock_t fd;
     pfd_elem_t *elem;
     int res;
     apr_status_t rv = APR_SUCCESS;
+    apr_port_pollset_t *pollset = (apr_port_pollset_t *) pollset_;
 
     pollset_lock_rings();
 
@@ -185,13 +191,14 @@
     return rv;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
+APR_DECLARE(apr_status_t) apr_port_pollset_remove(apr_pollset_t *pollset_,
                                              const apr_pollfd_t *descriptor)
 {
     apr_os_sock_t fd;
     pfd_elem_t *ep;
     apr_status_t rv = APR_SUCCESS;
     int res;
+    apr_port_pollset_t *pollset = (apr_port_pollset_t *) pollset_;
 
     pollset_lock_rings();
 
@@ -243,10 +250,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)
+APR_DECLARE(apr_status_t) apr_port_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;
@@ -254,6 +261,7 @@
     pfd_elem_t *ep;
     struct timespec tv, *tvptr;
     apr_status_t rv = APR_SUCCESS;
+    apr_port_pollset_t *pollset = (apr_port_pollset_t *) pollset_;
 
     if (timeout < 0) {
         tvptr = NULL;
@@ -340,4 +348,4 @@
     return rv;
 }
 
-#endif /* POLLSET_USES_PORT */
+#endif /* HAVE_PORT_CREATE */
Index: poll/unix/poll.c
===================================================================
--- poll/unix/poll.c	(revisjon 463892)
+++ poll/unix/poll.c	(arbeidskopi)
@@ -16,7 +16,7 @@
 
 #include "apr_arch_poll_private.h"
 
-#if defined(POLL_USES_POLL) || defined(POLLSET_USES_POLL)
+#ifdef HAVE_POLL
 
 #ifdef HAVE_ALLOCA_H
 #include <alloca.h>
@@ -62,16 +62,11 @@
     return rv;
 }
 
-#endif /* POLL_USES_POLL || POLLSET_USES_POLL */
-
-
-#ifdef POLL_USES_POLL
-
 #define SMALL_POLLSET_LIMIT  8
 
-APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, apr_int32_t num,
-                                   apr_int32_t *nsds, 
-                                   apr_interval_time_t timeout)
+APR_DECLARE(apr_status_t) apr_poll_poll(apr_pollfd_t *aprset, apr_int32_t num,
+					apr_int32_t *nsds, 
+					apr_interval_time_t timeout)
 {
     int i, num_to_poll;
 #ifdef HAVE_VLA
@@ -146,12 +141,7 @@
 }
 
 
-#endif /* POLL_USES_POLL */
-
-
-#ifdef POLLSET_USES_POLL
-
-struct apr_pollset_t
+struct apr_poll_pollset_t
 {
     apr_pool_t *pool;
     apr_uint32_t nelts;
@@ -161,11 +151,14 @@
     apr_pollfd_t *result_set;
 };
 
-APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
-                                             apr_uint32_t size,
-                                             apr_pool_t *p,
-                                             apr_uint32_t flags)
+typedef struct apr_poll_pollset_t apr_poll_pollset_t;
+
+APR_DECLARE(apr_status_t) apr_poll_pollset_create(apr_pollset_t **pollset_,
+						  apr_uint32_t size,
+						  apr_pool_t *p,
+						  apr_uint32_t flags)
 {
+    apr_poll_pollset_t **pollset = (apr_poll_pollset_t **) pollset_;
     if (flags & APR_POLLSET_THREADSAFE) {                
         *pollset = NULL;
         return APR_ENOTIMPL;
@@ -181,14 +174,16 @@
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset)
+APR_DECLARE(apr_status_t) apr_poll_pollset_destroy(apr_pollset_t *pollset)
 {
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset,
-                                          const apr_pollfd_t *descriptor)
+APR_DECLARE(apr_status_t) apr_poll_pollset_add(apr_pollset_t *pollset_,
+					       const apr_pollfd_t *descriptor)
 {
+    apr_poll_pollset_t *pollset = (apr_poll_pollset_t *) pollset_;
+    
     if (pollset->nelts == pollset->nalloc) {
         return APR_ENOMEM;
     }
@@ -209,9 +204,10 @@
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
-                                             const apr_pollfd_t *descriptor)
+APR_DECLARE(apr_status_t) apr_poll_pollset_remove(apr_pollset_t *pollset_,
+						  const apr_pollfd_t *descriptor)
 {
+    apr_poll_pollset_t *pollset = (apr_poll_pollset_t *) pollset_;
     apr_uint32_t i;
 
     for (i = 0; i < pollset->nelts; i++) {
@@ -237,13 +233,14 @@
     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)
+APR_DECLARE(apr_status_t) apr_poll_pollset_poll(apr_pollset_t *pollset_,
+						apr_interval_time_t timeout,
+						apr_int32_t *num,
+						const apr_pollfd_t **descriptors)
 {
     int rv;
     apr_uint32_t i, j;
+    apr_poll_pollset_t *pollset = (apr_poll_pollset_t *) pollset_;
 
     if (timeout > 0) {
         timeout /= 1000;
@@ -270,4 +267,4 @@
     return APR_SUCCESS;
 }
 
-#endif /* POLLSET_USES_POLL */
+#endif /* HAVE_POLL */
Index: poll/unix/epoll.c
===================================================================
--- poll/unix/epoll.c	(revisjon 463892)
+++ poll/unix/epoll.c	(arbeidskopi)
@@ -16,7 +16,7 @@
 
 #include "apr_arch_poll_private.h"
 
-#ifdef POLLSET_USES_EPOLL
+#if HAVE_EPOLL
 
 static apr_int16_t get_epoll_event(apr_int16_t event)
 {
@@ -56,7 +56,7 @@
     return rv;
 }
 
-struct apr_pollset_t
+struct apr_epoll_pollset_t
 {
     apr_pool_t *pool;
     apr_uint32_t nelts;
@@ -78,18 +78,22 @@
     APR_RING_HEAD(pfd_dead_ring_t, pfd_elem_t) dead_ring;
 };
 
+typedef struct apr_epoll_pollset_t apr_epoll_pollset_t;
+
 static apr_status_t backend_cleanup(void *p_)
 {
-    apr_pollset_t *pollset = (apr_pollset_t *) p_;
+    apr_epoll_pollset_t *pollset = (apr_epoll_pollset_t *) p_;
     close(pollset->epoll_fd);
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
-                                             apr_uint32_t size,
-                                             apr_pool_t *p,
-                                             apr_uint32_t flags)
+APR_DECLARE(apr_status_t) apr_epoll_pollset_create(apr_pollset_t **pollset_,
+						   apr_uint32_t size,
+						   apr_pool_t *p,
+						   apr_uint32_t flags)
 {
+    apr_epoll_pollset_t **pollset = (apr_epoll_pollset_t **) pollset_;
+
     apr_status_t rv;
     int fd;
 
@@ -132,18 +136,20 @@
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t *pollset)
+APR_DECLARE(apr_status_t) apr_epoll_pollset_destroy(apr_pollset_t *pollset_)
 {
+    apr_epoll_pollset_t *pollset = (apr_epoll_pollset_t *) pollset_;
     return apr_pool_cleanup_run(pollset->pool, pollset, backend_cleanup);
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset,
-                                          const apr_pollfd_t *descriptor)
+APR_DECLARE(apr_status_t) apr_epoll_pollset_add(apr_pollset_t *pollset_,
+						const apr_pollfd_t *descriptor)
 {
     struct epoll_event ev = {0};
     int ret = -1;
     pfd_elem_t *elem = NULL;
     apr_status_t rv = APR_SUCCESS;
+    apr_epoll_pollset_t *pollset = (apr_epoll_pollset_t *) pollset_;
 
     ev.events = get_epoll_event(descriptor->reqevents);
 
@@ -193,13 +199,14 @@
     return rv;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
-                                             const apr_pollfd_t *descriptor)
+APR_DECLARE(apr_status_t) apr_epoll_pollset_remove(apr_pollset_t *pollset_,
+						   const apr_pollfd_t *descriptor)
 {
     pfd_elem_t *ep;
     apr_status_t rv = APR_SUCCESS;
     struct epoll_event ev;
     int ret = -1;
+    apr_epoll_pollset_t *pollset = (apr_epoll_pollset_t *) pollset_;
 
     ev.events = get_epoll_event(descriptor->reqevents);
 
@@ -239,13 +246,14 @@
     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)
+APR_DECLARE(apr_status_t) apr_epoll_pollset_poll(apr_pollset_t *pollset_,
+						 apr_interval_time_t timeout,
+						 apr_int32_t *num,
+						 const apr_pollfd_t **descriptors)
 {
     int ret, i;
     apr_status_t rv = APR_SUCCESS;
+    apr_epoll_pollset_t *pollset = (apr_epoll_pollset_t *) pollset_;
 
     if (timeout > 0) {
         timeout /= 1000;
@@ -296,4 +304,4 @@
     return rv;
 }
 
-#endif /* POLLSET_USES_EPOLL */
+#endif /* HAVE_EPOLL */
Index: poll/unix/start.c
===================================================================
--- poll/unix/start.c	(revisjon 0)
+++ poll/unix/start.c	(revisjon 0)
@@ -0,0 +1,237 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "apr_arch_poll_private.h"
+
+typedef enum  {
+  SELECT,
+  POLL,
+  EPOLL,
+  KQUEUE,
+  PORT
+} implementation_t;
+
+static implementation_t pollset_impl;
+static implementation_t poll_impl;
+
+APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, apr_int32_t num,
+                                   apr_int32_t *nsds, 
+                                   apr_interval_time_t timeout)
+{
+    switch (poll_impl) {
+    case SELECT:
+	return apr_select_poll(aprset, num, nsds, timeout);
+	break;
+#ifdef HAVE_POLL
+    case POLL:
+	return apr_poll_poll(aprset, num, nsds, timeout);
+	break;
+#endif
+    }
+}
+
+
+APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset,
+                                             apr_uint32_t size,
+                                             apr_pool_t *p,
+                                             apr_uint32_t flags)
+{
+    switch (pollset_impl) {
+    case SELECT:
+	return apr_select_pollset_create(pollset, size, p, flags);
+	break;
+#ifdef HAVE_POLL
+    case POLL:
+	return apr_poll_pollset_create(pollset, size, p, flags);
+	break;
+#endif
+#ifdef HAVE_EPOLL
+    case EPOLL:
+	return apr_epoll_pollset_create(pollset, size, p, flags);
+	break;
+#endif
+#ifdef HAVE_KQUEUE
+    case KQUEUE:
+	return apr_kqueue_pollset_create(pollset, size, p, flags);
+	break;
+#endif
+#ifdef HAVE_PORT_CREATE
+    case PORT:
+	return apr_port_pollset_create(pollset, size, p, flags);
+	break;
+#endif
+    }
+}
+
+APR_DECLARE(apr_status_t) apr_pollset_destroy(apr_pollset_t * pollset)
+{
+    switch (pollset_impl) {
+    case SELECT:
+	return apr_select_pollset_destroy(pollset);
+	break;
+#ifdef HAVE_POLL
+    case POLL:
+	return apr_poll_pollset_destroy(pollset);
+	break;
+#endif
+#ifdef HAVE_EPOLL
+    case EPOLL:
+	return apr_epoll_pollset_destroy(pollset);
+	break;
+#endif
+#ifdef HAVE_KQUEUE
+    case KQUEUE:
+	return apr_kqueue_pollset_destroy(pollset);
+	break;
+#endif
+#ifdef HAVE_PORT_CREATE
+    case PORT:
+	return apr_port_pollset_destroy(pollset);
+	break;
+#endif
+    }
+}
+
+APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset,
+                                          const apr_pollfd_t *descriptor)
+{
+    switch (pollset_impl) {
+    case SELECT:
+	return apr_select_pollset_add(pollset, descriptor);
+	break;
+#ifdef HAVE_POLL
+    case POLL:
+	return apr_poll_pollset_add(pollset, descriptor);
+	break;
+#endif
+#ifdef HAVE_EPOLL
+    case EPOLL:
+	return apr_epoll_pollset_add(pollset, descriptor);
+	break;
+#endif
+#ifdef HAVE_KQUEUE
+    case KQUEUE:
+	return apr_kqueue_pollset_add(pollset, descriptor);
+	break;
+#endif
+#ifdef HAVE_PORT_CREATE
+    case PORT:
+	return apr_port_pollset_add(pollset, descriptor);
+	break;
+#endif
+    }
+}
+
+APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset,
+                                             const apr_pollfd_t *descriptor)
+{
+    switch (pollset_impl) {
+    case SELECT:
+	return apr_select_pollset_remove(pollset, descriptor);
+	break;
+#ifdef HAVE_POLL
+    case POLL:
+	return apr_poll_pollset_remove(pollset, descriptor);
+	break;
+#endif
+#ifdef HAVE_EPOLL
+    case EPOLL:
+	return apr_epoll_pollset_remove(pollset, descriptor);
+	break;
+#endif
+#ifdef HAVE_KQUEUE
+    case KQUEUE:
+	return apr_kqueue_pollset_remove(pollset, descriptor);
+	break;
+#endif
+#ifdef HAVE_PORT_CREATE
+    case PORT:
+	return apr_port_pollset_remove(pollset, descriptor);
+	break;
+#endif
+    }
+}
+
+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)
+{
+    switch (pollset_impl) {
+    case SELECT:
+	return apr_select_pollset_poll(pollset, timeout, num, descriptors);
+	break;
+#ifdef HAVE_POLL
+    case POLL:
+	return apr_poll_pollset_poll(pollset, timeout, num, descriptors);
+	break;
+#endif
+#ifdef HAVE_EPOLL
+    case EPOLL:
+	return apr_epoll_pollset_poll(pollset, timeout, num, descriptors);
+	break;
+#endif
+#ifdef HAVE_KQUEUE
+    case KQUEUE:
+	return apr_kqueue_pollset_poll(pollset, timeout, num, descriptors);
+	break;
+#endif
+#ifdef HAVE_PORT_CREATE
+    case PORT:
+	return apr_port_pollset_poll(pollset, timeout, num, descriptors);
+	break;
+#endif
+    }
+}
+
+
+APR_DECLARE(void) apr_poll_init()
+{
+#ifdef HAVE_EPOLL
+    int epoll_fd;
+#endif
+
+#ifdef HAVE_POLL
+    poll_impl = POLL;
+#else
+    poll_impl = SELECT;
+#endif
+
+#ifdef HAVE_EPOLL
+    epoll_fd = epoll_create(5);
+    if (epoll_fd > -1) {
+        close(epoll_fd);
+	pollset_impl = EPOLL;
+	return;
+    }
+#endif
+
+#ifdef HAVE_KQUEUE
+    pollset_impl = KQUEUE;
+    return;
+#endif
+
+#ifdef HAVE_PORT_CREATE
+    pollset_impl = PORT;
+    return;
+#endif
+
+#ifdef HAVE_POLL
+    pollset_impl = POLL;
+#else
+    pollset_impl = SELECT;
+#endif
+}

Reply via email to