apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j..@apache.org
Subject svn commit: r821199 [2/2] - in /apr/apr/branches/1.4.x: ./ include/ include/arch/unix/ poll/os2/ poll/unix/
Date Fri, 02 Oct 2009 23:24:57 GMT
Modified: apr/apr/branches/1.4.x/poll/unix/port.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.4.x/poll/unix/port.c?rev=821199&r1=821198&r2=821199&view=diff
==============================================================================
--- apr/apr/branches/1.4.x/poll/unix/port.c (original)
+++ apr/apr/branches/1.4.x/poll/unix/port.c Fri Oct  2 23:24:56 2009
@@ -14,11 +14,17 @@
  * 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"
 #include "apr_arch_inherit.h"
 
-#ifdef POLLSET_USES_PORT
+#if defined(HAVE_PORT_CREATE)
 
 static apr_int16_t get_event(apr_int16_t event)
 {
@@ -56,16 +62,11 @@
 }
 
 
-struct apr_pollset_t
+struct apr_pollset_private_t
 {
-    apr_pool_t *pool;
-    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;
@@ -137,138 +138,67 @@
     return rv;
 }
 
-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
-    if (flags & APR_POLLSET_WAKEABLE) {
-        /* Add room for wakeup descriptor */
-        size++;
-    }
-    (*pollset)->waiting = 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_get_netos_error();
     }
 
     {
         int flags;
 
-        if ((flags = fcntl((*pollset)->port_fd, F_GETFD)) == -1)
+        if ((flags = fcntl(pollset->p->port_fd, F_GETFD)) == -1)
             return errno;
 
         flags |= FD_CLOEXEC;
-        if (fcntl((*pollset)->port_fd, F_SETFD, flags) == -1)
+        if (fcntl(pollset->p->port_fd, F_SETFD, flags) == -1)
             return errno;
     }
 
-    (*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;
@@ -277,13 +207,14 @@
 
     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 {
         elem = (pfd_elem_t *) apr_palloc(pollset->pool, sizeof(pfd_elem_t));
         APR_RING_ELEM_INIT(elem, link);
+        elem->on_query_ring = 0;
     }
     elem->pfd = *descriptor;
 
@@ -297,20 +228,21 @@
     /* If another thread is polling, notify the kernel immediately; otherwise,
      * wait until the next call to apr_pollset_poll().
      */
-    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_get_netos_error();
-            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 {
-            APR_RING_INSERT_TAIL(&(pollset->query_ring), elem, pfd_elem_t, link);
+            elem->on_query_ring = 1;
+            APR_RING_INSERT_TAIL(&(pollset->p->query_ring), elem, pfd_elem_t, link);
         }
     } 
     else {
-        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();
@@ -318,14 +250,15 @@
     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;
     apr_status_t rv = APR_SUCCESS;
     int res;
     int err = 0;
+    int found;
 
     pollset_lock_rings();
 
@@ -336,42 +269,60 @@
         fd = descriptor->desc.f->filedes;
     }
 
-    res = port_dissociate(pollset->port_fd, PORT_SOURCE_FD, fd);
-
-    if (res < 0) {
-        err = errno;
-        rv = APR_NOTFOUND;
-    }
-
-    for (ep = APR_RING_FIRST(&(pollset->query_ring));
-         ep != APR_RING_SENTINEL(&(pollset->query_ring),
+    /* Search the add ring first.  This ring is often shorter,
+     * and it often contains the descriptor being removed.  
+     * (For the common scenario where apr_pollset_poll() 
+     * returns activity for the descriptor and the descriptor
+     * is then removed from the pollset, it will have just 
+     * been moved to the add ring by apr_pollset_poll().)
+     *
+     * If it is on the add ring, it isn't associated with the
+     * event port yet/anymore.
+     */
+    found = 0;
+    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) {
+            found = 1;
             APR_RING_REMOVE(ep, link);
-            APR_RING_INSERT_TAIL(&(pollset->dead_ring),
+            APR_RING_INSERT_TAIL(&(pollset->p->free_ring),
                                  ep, pfd_elem_t, link);
-            if (ENOENT == err) {
-                rv = APR_SUCCESS;
-            }
             break;
         }
     }
 
-    for (ep = APR_RING_FIRST(&(pollset->add_ring));
-         ep != APR_RING_SENTINEL(&(pollset->add_ring),
-                                 pfd_elem_t, link);
-         ep = APR_RING_NEXT(ep, link)) {
+    if (!found) {
+        res = port_dissociate(pollset->p->port_fd, PORT_SOURCE_FD, fd);
 
-        if (descriptor->desc.s == ep->pfd.desc.s) {
-            APR_RING_REMOVE(ep, link);
-            APR_RING_INSERT_TAIL(&(pollset->dead_ring),
-                                 ep, pfd_elem_t, link);
-            if (ENOENT == err) {
-                rv = APR_SUCCESS;
+        if (res < 0) {
+            /* The expected case for this failure is that another
+             * thread's call to port_getn() returned this fd and
+             * disassociated the fd from the event port, and 
+             * impl_pollset_poll() is blocked on the ring lock,
+             * which this thread holds.
+             */
+            err = errno;
+            rv = APR_NOTFOUND;
+        }
+
+        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);
+                ep->on_query_ring = 0;
+                APR_RING_INSERT_TAIL(&(pollset->p->dead_ring),
+                                     ep, pfd_elem_t, link);
+                if (ENOENT == err) {
+                    rv = APR_SUCCESS;
+                }
+                break;
             }
-            break;
         }
     }
 
@@ -380,10 +331,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;
@@ -396,10 +347,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) {
@@ -409,30 +360,31 @@
             fd = ep->pfd.desc.f->filedes;
         }
 
-        ret = port_associate(pollset->port_fd, PORT_SOURCE_FD, 
+        ret = port_associate(pollset->p->port_fd, PORT_SOURCE_FD, 
                              fd, get_event(ep->pfd.reqevents), ep);
         if (ret < 0) {
             rv = apr_get_netos_error();
-            APR_RING_INSERT_TAIL(&(pollset->free_ring), ep, pfd_elem_t, link);
+            APR_RING_INSERT_TAIL(&(pollset->p->free_ring), ep, pfd_elem_t, link);
             break;
         }
 
-        APR_RING_INSERT_TAIL(&(pollset->query_ring), ep, pfd_elem_t, link);
+        ep->on_query_ring = 1;
+        APR_RING_INSERT_TAIL(&(pollset->p->query_ring), ep, pfd_elem_t, link);
     }
 
     pollset_unlock_rings();
 
     if (rv != APR_SUCCESS) {
-        apr_atomic_dec32(&pollset->waiting);
+        apr_atomic_dec32(&pollset->p->waiting);
         return rv;
     }
 
-    rv = call_port_getn(pollset->port_fd, pollset->port_set, pollset->nalloc,
-                        &nget, timeout);
+    rv = call_port_getn(pollset->p->port_fd, pollset->p->port_set, 
+                        pollset->nalloc, &nget, timeout);
 
     /* 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 (nget) {
@@ -440,31 +392,38 @@
         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);
-
-                APR_RING_REMOVE((pfd_elem_t*)pollset->port_set[i].portev_user,
-                                link);
-                APR_RING_INSERT_TAIL(&(pollset->add_ring), 
-                                (pfd_elem_t*)pollset->port_set[i].portev_user,
-                                pfd_elem_t, link);
+                pollset->p->result_set[j] = fp;            
+                pollset->p->result_set[j].rtnevents =
+                    get_revent(pollset->p->port_set[i].portev_events);
+
+                /* If the ring element is still on the query ring, move it
+                 * to the add ring for re-association with the event port
+                 * later.  (It may have already been moved to the dead ring
+                 * by a call to pollset_remove on another thread.)
+                 */
+                ep = (pfd_elem_t *)pollset->p->port_set[i].portev_user;
+                if (ep->on_query_ring) {
+                    APR_RING_REMOVE(ep, link);
+                    ep->on_query_ring = 0;
+                    APR_RING_INSERT_TAIL(&(pollset->p->add_ring), ep,
+                                         pfd_elem_t, link);
+                }
                 j++;
             }
         }
         pollset_unlock_rings();
-        if ((*num) = j) { /* any event besides wakeup pipe? */
+        if ((*num = j)) { /* any event besides wakeup pipe? */
             rv = APR_SUCCESS;
             if (descriptors) {
-                *descriptors = pollset->result_set;
+                *descriptors = pollset->p->result_set;
             }
         }
     }
@@ -472,72 +431,61 @@
     pollset_lock_rings();
 
     /* Shift all PFDs in the Dead Ring to the 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();
+    pollcb->fd = port_create();
 
-    if (fd < 0) {
-        *pollcb = NULL;
+    if (pollcb->fd < 0) {
         return apr_get_netos_error();
     }
 
     {
         int flags;
 
-        if ((flags = fcntl(fd, F_GETFD)) == -1)
+        if ((flags = fcntl(pollcb->fd, F_GETFD)) == -1)
             return errno;
 
         flags |= FD_CLOEXEC;
-        if (fcntl(fd, F_SETFD, flags) == -1)
+        if (fcntl(pollcb->fd, F_SETFD, flags) == -1)
             return errno;
     }
 
-    *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, apr_pool_cleanup_null);
 
     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;
 
@@ -548,7 +496,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) {
@@ -558,8 +506,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;
 
@@ -570,7 +518,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;
@@ -579,22 +527,22 @@
     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)
 {
     apr_pollfd_t *pollfd;
     apr_status_t rv;
     unsigned int i, nget = pollcb->nalloc;
 
-    rv = call_port_getn(pollcb->port_fd, pollcb->port_set, pollcb->nalloc,
+    rv = call_port_getn(pollcb->fd, pollcb->pollset.port, pollcb->nalloc,
                         &nget, timeout);
 
     if (nget) {
         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) {
@@ -607,4 +555,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 */

Modified: apr/apr/branches/1.4.x/poll/unix/select.c
URL: http://svn.apache.org/viewvc/apr/apr/branches/1.4.x/poll/unix/select.c?rev=821199&r1=821198&r2=821199&view=diff
==============================================================================
--- apr/apr/branches/1.4.x/poll/unix/select.c (original)
+++ apr/apr/branches/1.4.x/poll/unix/select.c Fri Oct  2 23:24:56 2009
@@ -23,8 +23,8 @@
 #include "apr_poll.h"
 #include "apr_time.h"
 #include "apr_portable.h"
-#include "apr_arch_networkio.h"
 #include "apr_arch_file_io.h"
+#include "apr_arch_networkio.h"
 #include "apr_arch_poll_private.h"
 
 #ifdef POLL_USES_SELECT
@@ -167,191 +167,49 @@
 
 #endif /* POLL_USES_SELECT */
 
-#ifdef POLLSET_USES_SELECT
-
-struct apr_pollset_t
+struct apr_pollset_private_t
 {
-    apr_pool_t *pool;
-
-    apr_uint32_t nelts;
-    apr_uint32_t nalloc;
     fd_set readset, writeset, exceptset;
     int maxfd;
     apr_pollfd_t *query_set;
     apr_pollfd_t *result_set;
     apr_uint32_t flags;
-    /* Pipe descriptors used for wakeup */
-    apr_file_t *wakeup_pipe[2];
 #ifdef NETWARE
     int set_type;
 #endif
 };
 
-#if !APR_FILES_AS_SOCKETS
-#if defined (WIN32)
-
-extern apr_status_t
-apr_file_socket_pipe_create(apr_file_t **in,
-                            apr_file_t **out,
-                            apr_pool_t *p);
-
-extern apr_status_t
-apr_file_socket_pipe_close(apr_file_t *file);
-
-/* Create a dummy wakeup socket pipe for interrupting the poller
- */
-static apr_status_t create_wakeup_pipe(apr_pollset_t *pollset)
-{
-    apr_status_t rv;
-    apr_pollfd_t fd;
-
-    if ((rv = apr_file_socket_pipe_create(&pollset->wakeup_pipe[0],
-                                          &pollset->wakeup_pipe[1],
-                                          pollset->pool)) != APR_SUCCESS)
-        return rv;
-    fd.reqevents = APR_POLLIN;
-    fd.desc_type = APR_POLL_FILE;
-    fd.desc.f = pollset->wakeup_pipe[0];
-    /* Add the pipe to the pollset
-     */
-    return apr_pollset_add(pollset, &fd);
-}
-#else  /* !WIN32 */
-static apr_status_t create_wakeup_pipe(apr_pollset_t *pollset)
-{
-    return APR_ENOTIMPL;
-}
-
-static apr_status_t apr_file_socket_pipe_close(apr_file_t *file)
-{
-    return APR_ENOTIMPL;
-}
-
-#endif /* WIN32 */
-#else  /* APR_FILES_AS_SOCKETS */
-
-/* Create a dummy wakeup pipe for interrupting the poller
- */
-static apr_status_t create_wakeup_pipe(apr_pollset_t *pollset)
-{
-    apr_status_t rv;
-    apr_pollfd_t fd;
-
-    if ((rv = apr_file_pipe_create(&pollset->wakeup_pipe[0],
-                                   &pollset->wakeup_pipe[1],
-                                   pollset->pool)) != APR_SUCCESS)
-        return rv;
-    fd.reqevents = APR_POLLIN;
-    fd.desc_type = APR_POLL_FILE;
-    fd.desc.f = pollset->wakeup_pipe[0];
-    /* Add the pipe to the pollset
-     */
-    return apr_pollset_add(pollset, &fd);
-}
-#endif /* !APR_FILES_AS_SOCKETS */
-
-/* Read and discard what's ever in the wakeup pipe.
- */
-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]) {
-#if APR_FILES_AS_SOCKETS
-            apr_file_close(pollset->wakeup_pipe[0]);
-#else
-            apr_file_socket_pipe_close(pollset->wakeup_pipe[0]);
-#endif
-            pollset->wakeup_pipe[0] = NULL;
-        }
-        if (pollset->wakeup_pipe[1]) {
-#if APR_FILES_AS_SOCKETS
-            apr_file_close(pollset->wakeup_pipe[1]);
-#else
-            apr_file_socket_pipe_close(pollset->wakeup_pipe[1]);
-#endif
-            pollset->wakeup_pipe[1] = NULL;
-        }
-    }
-
-    return APR_SUCCESS;
-}
-
-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;
+        pollset->p = NULL;
         return APR_ENOTIMPL;
     }
-    if (flags & APR_POLLSET_WAKEABLE) {
-        /* Add room for wakeup descriptor */
-        size++;
-    }
 #ifdef FD_SETSIZE
     if (size > FD_SETSIZE) {
-        *pollset = NULL;
+        pollset->p = NULL;
         return APR_EINVAL;
     }
 #endif
-    *pollset = apr_palloc(p, sizeof(**pollset));
-    (*pollset)->nelts = 0;
-    (*pollset)->nalloc = size;
-    (*pollset)->pool = p;
-    (*pollset)->flags = flags;
-    FD_ZERO(&((*pollset)->readset));
-    FD_ZERO(&((*pollset)->writeset));
-    FD_ZERO(&((*pollset)->exceptset));
-    (*pollset)->maxfd = 0;
+    pollset->p = apr_palloc(p, sizeof(apr_pollset_private_t));
+    FD_ZERO(&(pollset->p->readset));
+    FD_ZERO(&(pollset->p->writeset));
+    FD_ZERO(&(pollset->p->exceptset));
+    pollset->p->maxfd = 0;
 #ifdef NETWARE
-    (*pollset)->set_type = APR_NO_DESC;
+    pollset->p->set_type = APR_NO_DESC;
 #endif
-    (*pollset)->query_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
-    (*pollset)->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
+    pollset->p->query_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
+    pollset->p->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;
 }
 
-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;
-}
-
-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;
 
@@ -359,16 +217,16 @@
         return APR_ENOMEM;
     }
 
-    pollset->query_set[pollset->nelts] = *descriptor;
+    pollset->p->query_set[pollset->nelts] = *descriptor;
 
     if (descriptor->desc_type == APR_POLL_SOCKET) {
 #ifdef NETWARE
         /* NetWare can't handle mixed descriptor types in select() */
-        if (HAS_PIPES(pollset->set_type)) {
+        if (HAS_PIPES(pollset->p->set_type)) {
             return APR_EBADF;
         }
         else {
-            pollset->set_type = APR_POLL_SOCKET;
+            pollset->p->set_type = APR_POLL_SOCKET;
         }
 #endif
         fd = descriptor->desc.s->socketdes;
@@ -376,16 +234,15 @@
     else {
 #if !APR_FILES_AS_SOCKETS
         if ((pollset->flags & APR_POLLSET_WAKEABLE) &&
-            descriptor->desc.f == pollset->wakeup_pipe[0]) {
+            descriptor->desc.f == pollset->wakeup_pipe[0])
             fd = (apr_os_sock_t)descriptor->desc.f->filedes;
-        }
         else
             return APR_EBADF;
 #else
 #ifdef NETWARE
         /* NetWare can't handle mixed descriptor types in select() */
-        if (descriptor->desc.f->is_pipe && !HAS_SOCKETS(pollset->set_type))
{
-            pollset->set_type = APR_POLL_FILE;
+        if (descriptor->desc.f->is_pipe && !HAS_SOCKETS(pollset->p->set_type))
{
+            pollset->p->set_type = APR_POLL_FILE;
             fd = descriptor->desc.f->filedes;
         }
         else {
@@ -403,24 +260,24 @@
     }
 #endif
     if (descriptor->reqevents & APR_POLLIN) {
-        FD_SET(fd, &(pollset->readset));
+        FD_SET(fd, &(pollset->p->readset));
     }
     if (descriptor->reqevents & APR_POLLOUT) {
-        FD_SET(fd, &(pollset->writeset));
+        FD_SET(fd, &(pollset->p->writeset));
     }
     if (descriptor->reqevents &
         (APR_POLLPRI | APR_POLLERR | APR_POLLHUP | APR_POLLNVAL)) {
-        FD_SET(fd, &(pollset->exceptset));
+        FD_SET(fd, &(pollset->p->exceptset));
     }
-    if ((int) fd > pollset->maxfd) {
-        pollset->maxfd = (int) fd;
+    if ((int) fd > pollset->p->maxfd) {
+        pollset->p->maxfd = (int) fd;
     }
     pollset->nelts++;
     return APR_SUCCESS;
 }
 
-APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t * pollset,
-                                             const apr_pollfd_t * descriptor)
+static apr_status_t impl_pollset_remove(apr_pollset_t * pollset,
+                                        const apr_pollfd_t * descriptor)
 {
     apr_uint32_t i;
     apr_os_sock_t fd;
@@ -437,25 +294,25 @@
     }
 
     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->query_set[dst] = pollset->query_set[i];
+                    pollset->p->query_set[dst] = pollset->p->query_set[i];
                     dst++;
                 }
             }
-            FD_CLR(fd, &(pollset->readset));
-            FD_CLR(fd, &(pollset->writeset));
-            FD_CLR(fd, &(pollset->exceptset));
-            if (((int) fd == pollset->maxfd) && (pollset->maxfd > 0)) {
-                pollset->maxfd--;
+            FD_CLR(fd, &(pollset->p->readset));
+            FD_CLR(fd, &(pollset->p->writeset));
+            FD_CLR(fd, &(pollset->p->exceptset));
+            if (((int) fd == pollset->p->maxfd) && (pollset->p->maxfd
> 0)) {
+                pollset->p->maxfd--;
             }
             return APR_SUCCESS;
         }
@@ -464,10 +321,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 rs;
     apr_uint32_t i, j;
@@ -495,18 +352,18 @@
         tvptr = &tv;
     }
 
-    memcpy(&readset, &(pollset->readset), sizeof(fd_set));
-    memcpy(&writeset, &(pollset->writeset), sizeof(fd_set));
-    memcpy(&exceptset, &(pollset->exceptset), sizeof(fd_set));
+    memcpy(&readset, &(pollset->p->readset), sizeof(fd_set));
+    memcpy(&writeset, &(pollset->p->writeset), sizeof(fd_set));
+    memcpy(&exceptset, &(pollset->p->exceptset), sizeof(fd_set));
 
 #ifdef NETWARE
-    if (HAS_PIPES(pollset->set_type)) {
-        rs = pipe_select(pollset->maxfd + 1, &readset, &writeset, &exceptset,
+    if (HAS_PIPES(pollset->p->set_type)) {
+        rs = pipe_select(pollset->p->maxfd + 1, &readset, &writeset, &exceptset,
                          tvptr);
     }
     else
 #endif
-        rs = select(pollset->maxfd + 1, &readset, &writeset, &exceptset,
+        rs = select(pollset->p->maxfd + 1, &readset, &writeset, &exceptset,
                     tvptr);
 
     (*num) = rs;
@@ -519,13 +376,13 @@
     j = 0;
     for (i = 0; i < pollset->nelts; i++) {
         apr_os_sock_t fd;
-        if (pollset->query_set[i].desc_type == APR_POLL_SOCKET) {
-            fd = pollset->query_set[i].desc.s->socketdes;
+        if (pollset->p->query_set[i].desc_type == APR_POLL_SOCKET) {
+            fd = pollset->p->query_set[i].desc.s->socketdes;
         }
         else {
             if ((pollset->flags & APR_POLLSET_WAKEABLE) &&
-                pollset->query_set[i].desc.f == pollset->wakeup_pipe[0]) {
-                drain_wakeup_pipe(pollset);
+                pollset->p->query_set[i].desc.f == pollset->wakeup_pipe[0]) {
+                apr_pollset_drain_wakeup_pipe(pollset);
                 rv = APR_EINTR;
                 continue;
             }
@@ -533,22 +390,22 @@
 #if !APR_FILES_AS_SOCKETS
                 return APR_EBADF;
 #else
-                fd = pollset->query_set[i].desc.f->filedes;
+                fd = pollset->p->query_set[i].desc.f->filedes;
 #endif
             }
         }
         if (FD_ISSET(fd, &readset) || FD_ISSET(fd, &writeset) ||
             FD_ISSET(fd, &exceptset)) {
-            pollset->result_set[j] = pollset->query_set[i];
-            pollset->result_set[j].rtnevents = 0;
+            pollset->p->result_set[j] = pollset->p->query_set[i];
+            pollset->p->result_set[j].rtnevents = 0;
             if (FD_ISSET(fd, &readset)) {
-                pollset->result_set[j].rtnevents |= APR_POLLIN;
+                pollset->p->result_set[j].rtnevents |= APR_POLLIN;
             }
             if (FD_ISSET(fd, &writeset)) {
-                pollset->result_set[j].rtnevents |= APR_POLLOUT;
+                pollset->p->result_set[j].rtnevents |= APR_POLLOUT;
             }
             if (FD_ISSET(fd, &exceptset)) {
-                pollset->result_set[j].rtnevents |= APR_POLLERR;
+                pollset->p->result_set[j].rtnevents |= APR_POLLERR;
             }
             j++;
         }
@@ -557,45 +414,17 @@
         rv = APR_SUCCESS;
 
     if (descriptors)
-        *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;
-}
-
-APR_DECLARE(apr_status_t) apr_pollcb_create(apr_pollcb_t **pollcb,
-                                            apr_uint32_t size,
-                                            apr_pool_t *p,
-                                            apr_uint32_t flags)
-{
-    return APR_ENOTIMPL;
-}
-
-APR_DECLARE(apr_status_t) apr_pollcb_add(apr_pollcb_t *pollcb,
-                                         apr_pollfd_t *descriptor)
-{
-    return APR_ENOTIMPL;
-}
-
-APR_DECLARE(apr_status_t) apr_pollcb_remove(apr_pollcb_t *pollcb,
-                                            apr_pollfd_t *descriptor)
-{
-    return APR_ENOTIMPL;
-}
-
-
-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;
-}
+static apr_pollset_provider_t impl = {
+    impl_pollset_create,
+    impl_pollset_add,
+    impl_pollset_remove,
+    impl_pollset_poll,
+    NULL,
+    "select"
+};
 
-#endif /* POLLSET_USES_SELECT */
+apr_pollset_provider_t *apr_pollset_provider_select = &impl;



Mime
View raw message