apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From traw...@apache.org
Subject svn commit: r748951 - in /apr/apr/trunk: include/apr_poll.h poll/unix/kqueue.c
Date Sun, 01 Mar 2009 02:22:39 GMT
Author: trawick
Date: Sun Mar  1 02:22:38 2009
New Revision: 748951

URL: http://svn.apache.org/viewvc?rev=748951&view=rev
Log:
Allow the kqueue pollset implementation to support checking both APR_POLLIN and
APR_POLLOUT for the same descriptor.  This requires separate kevent structures
for both conditions.

Importantly, if both conditions are present, they will be returned in separate
apr_pollfd_t structures with this implementation (to avoid the cycles to coalesce 
into the minimal number of structures).


Modified:
    apr/apr/trunk/include/apr_poll.h
    apr/apr/trunk/poll/unix/kqueue.c

Modified: apr/apr/trunk/include/apr_poll.h
URL: http://svn.apache.org/viewvc/apr/apr/trunk/include/apr_poll.h?rev=748951&r1=748950&r2=748951&view=diff
==============================================================================
--- apr/apr/trunk/include/apr_poll.h (original)
+++ apr/apr/trunk/include/apr_poll.h Sun Mar  1 02:22:38 2009
@@ -241,6 +241,9 @@
  *         APR_POLLSET_WAKEABLE, apr_pollset_wakeup() has been called while
  *         waiting for activity, and there were no signalled descriptors at the
  *         time of the wakeup call.
+ * @remark Multiple signalled conditions for the same descriptor may be reported
+ *         in one or more returned apr_pollfd_t structures, depending on the
+ *         implementation.
  */
 APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset,
                                            apr_interval_time_t timeout,

Modified: apr/apr/trunk/poll/unix/kqueue.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/poll/unix/kqueue.c?rev=748951&r1=748950&r2=748951&view=diff
==============================================================================
--- apr/apr/trunk/poll/unix/kqueue.c (original)
+++ apr/apr/trunk/poll/unix/kqueue.c Sun Mar  1 02:22:38 2009
@@ -44,7 +44,9 @@
 struct apr_pollset_private_t
 {
     int kqueue_fd;
-    struct kevent kevent;
+    struct kevent in_kevent;
+    struct kevent out_kevent;
+    apr_uint32_t setsize;
     struct kevent *ke_set;
     apr_pollfd_t *result_set;
 #if APR_HAS_THREADS
@@ -88,10 +90,19 @@
     }
 #endif
 
+    /* POLLIN and POLLOUT are represented in different returned
+     * events, so we need 2 entries per descriptor in the result set,
+     * both for what is returned by kevent() and what is returned to
+     * the caller of apr_pollset_poll() (since it doesn't spend the
+     * CPU to coalesce separate APR_POLLIN and APR_POLLOUT events
+     * for the same descriptor)
+     */
+    pollset->p->setsize = 2 * size;
+
     pollset->p->ke_set =
-        (struct kevent *) apr_palloc(p, size * sizeof(struct kevent));
+        (struct kevent *) apr_palloc(p, pollset->p->setsize * sizeof(struct kevent));
 
-    memset(pollset->p->ke_set, 0, size * sizeof(struct kevent));
+    memset(pollset->p->ke_set, 0, pollset->p->setsize * sizeof(struct kevent));
 
     pollset->p->kqueue_fd = kqueue();
 
@@ -110,7 +121,7 @@
             return errno;
     }
 
-    pollset->p->result_set = apr_palloc(p, size * sizeof(apr_pollfd_t));
+    pollset->p->result_set = apr_palloc(p, pollset->p->setsize * sizeof(apr_pollfd_t));
 
     APR_RING_INIT(&pollset->p->query_ring, pfd_elem_t, link);
     APR_RING_INIT(&pollset->p->free_ring, pfd_elem_t, link);
@@ -146,18 +157,18 @@
     }
 
     if (descriptor->reqevents & APR_POLLIN) {
-        EV_SET(&pollset->p->kevent, fd, EVFILT_READ, EV_ADD, 0, 0, elem);
+        EV_SET(&pollset->p->in_kevent, fd, EVFILT_READ, EV_ADD, 0, 0, elem);
 
-        if (kevent(pollset->p->kqueue_fd, &pollset->p->kevent, 1, NULL, 0,
+        if (kevent(pollset->p->kqueue_fd, &pollset->p->in_kevent, 1, NULL,
0,
                    NULL) == -1) {
             rv = apr_get_netos_error();
         }
     }
 
     if (descriptor->reqevents & APR_POLLOUT && rv == APR_SUCCESS) {
-        EV_SET(&pollset->p->kevent, fd, EVFILT_WRITE, EV_ADD, 0, 0, elem);
+        EV_SET(&pollset->p->out_kevent, fd, EVFILT_WRITE, EV_ADD, 0, 0, elem);
 
-        if (kevent(pollset->p->kqueue_fd, &pollset->p->kevent, 1, NULL, 0,
+        if (kevent(pollset->p->kqueue_fd, &pollset->p->out_kevent, 1, NULL,
0,
                    NULL) == -1) {
             rv = apr_get_netos_error();
         }
@@ -193,18 +204,18 @@
     }
 
     if (descriptor->reqevents & APR_POLLIN) {
-        EV_SET(&pollset->p->kevent, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
+        EV_SET(&pollset->p->in_kevent, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
 
-        if (kevent(pollset->p->kqueue_fd, &pollset->p->kevent, 1, NULL, 0,
+        if (kevent(pollset->p->kqueue_fd, &pollset->p->in_kevent, 1, NULL,
0,
                    NULL) == -1) {
             rv = APR_NOTFOUND;
         }
     }
 
     if (descriptor->reqevents & APR_POLLOUT && rv == APR_SUCCESS) {
-        EV_SET(&pollset->p->kevent, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
+        EV_SET(&pollset->p->out_kevent, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
 
-        if (kevent(pollset->p->kqueue_fd, &pollset->p->kevent, 1, NULL, 0,
+        if (kevent(pollset->p->kqueue_fd, &pollset->p->out_kevent, 1, NULL,
0,
                    NULL) == -1) {
             rv = APR_NOTFOUND;
         }
@@ -250,7 +261,7 @@
     }
 
     ret = kevent(pollset->p->kqueue_fd, NULL, 0, pollset->p->ke_set,
-                 pollset->nalloc, tvptr);
+                 pollset->p->setsize, tvptr);
     (*num) = ret;
     if (ret < 0) {
         rv = apr_get_netos_error();
@@ -337,7 +348,7 @@
     }
  
     pollcb->fd = fd;
-    pollcb->pollset.ke = (struct kevent *)apr_pcalloc(p, size * sizeof(struct kevent));
+    pollcb->pollset.ke = (struct kevent *)apr_pcalloc(p, 2 * size * sizeof(struct kevent));
     apr_pool_cleanup_register(p, pollcb, cb_cleanup, apr_pool_cleanup_null);
     
     return APR_SUCCESS;
@@ -431,7 +442,7 @@
         tvptr = &tv;
     }
     
-    ret = kevent(pollcb->fd, NULL, 0, pollcb->pollset.ke, pollcb->nalloc,
+    ret = kevent(pollcb->fd, NULL, 0, pollcb->pollset.ke, 2 * pollcb->nalloc,
                  tvptr);
 
     if (ret < 0) {



Mime
View raw message