apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From traw...@apache.org
Subject svn commit: r807265 - /apr/apr/branches/1.4.x/poll/unix/port.c
Date Mon, 24 Aug 2009 15:03:58 GMT
Author: trawick
Date: Mon Aug 24 15:03:57 2009
New Revision: 807265

URL: http://svn.apache.org/viewvc?rev=807265&view=rev
Log:
backport r807263 from trunk:

Fix an error handling issue in the Event Port backend for APR pollsets.
(ETIME is sometimes reported along with an event.)

PR: 47645

Modified:
    apr/apr/branches/1.4.x/poll/unix/port.c

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=807265&r1=807264&r2=807265&view=diff
==============================================================================
--- apr/apr/branches/1.4.x/poll/unix/port.c (original)
+++ apr/apr/branches/1.4.x/poll/unix/port.c Mon Aug 24 15:03:57 2009
@@ -85,6 +85,58 @@
     volatile apr_uint32_t waiting;
 };
 
+static apr_status_t call_port_getn(int port, port_event_t list[], 
+                                   unsigned int max, unsigned int *nget,
+                                   apr_interval_time_t timeout)
+{
+    struct timespec tv, *tvptr;
+    int ret;
+    apr_status_t rv = APR_SUCCESS;
+
+    if (timeout < 0) {
+        tvptr = NULL;
+    }
+    else {
+        tv.tv_sec = (long) apr_time_sec(timeout);
+        tv.tv_nsec = (long) apr_time_usec(timeout) * 1000;
+        tvptr = &tv;
+    }
+
+    ret = port_getn(port, list, max, nget, tvptr);
+
+    if (ret < 0) {
+        rv = apr_get_netos_error();
+
+        switch(rv) {
+        case EINTR:
+        case ETIME:
+            if (*nget > 0) {
+                /* This confusing API can return an event at the same time
+                 * that it reports EINTR or ETIME.  If that occurs, just
+                 * report the event.
+                 * (Maybe it will be simplified; see thread
+                 *   http://mail.opensolaris.org
+                 *   /pipermail/networking-discuss/2009-August/011979.html
+                 *  This code will still work afterwards.)
+                 */
+                rv = APR_SUCCESS;
+                break;
+            }
+            if (rv == ETIME) {
+                rv = APR_TIMEUP;
+            }
+        /* fall-through */
+        default:
+            *nget = 0;
+        }
+    }
+    else if (*nget == 0) {
+        rv = APR_TIMEUP;
+    }
+
+    return rv;
+}
+
 static apr_status_t backend_cleanup(void *p_)
 {
     apr_pollset_t *pollset = (apr_pollset_t *) p_;
@@ -337,19 +389,9 @@
     int ret, i, j;
     unsigned int nget;
     pfd_elem_t *ep;
-    struct timespec tv, *tvptr;
     apr_status_t rv = APR_SUCCESS;
     apr_pollfd_t fp;
 
-    if (timeout < 0) {
-        tvptr = NULL;
-    }
-    else {
-        tv.tv_sec = (long) apr_time_sec(timeout);
-        tv.tv_nsec = (long) apr_time_usec(timeout) * 1000;
-        tvptr = &tv;
-    }
-
     nget = 1;
 
     pollset_lock_rings();
@@ -385,27 +427,15 @@
         return rv;
     }
 
-    ret = port_getn(pollset->port_fd, pollset->port_set, pollset->nalloc,
-                    &nget, tvptr);
+    rv = call_port_getn(pollset->port_fd, pollset->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);
-    (*num) = nget;
 
-    if (ret == -1) {
-        (*num) = 0;
-        if (errno == ETIME) {
-            rv = APR_TIMEUP;
-        }
-        else {
-            rv = apr_get_netos_error();
-        }
-    }
-    else if (nget == 0) {
-        rv = APR_TIMEUP;
-    }
-    else {
+    (*num) = nget;
+    if (nget) {
 
         pollset_lock_rings();
 
@@ -554,36 +584,14 @@
                                           apr_pollcb_cb_t func,
                                           void *baton)
 {
-    int ret;
     apr_pollfd_t *pollfd;
-    struct timespec tv, *tvptr;
-    apr_status_t rv = APR_SUCCESS;
+    apr_status_t rv;
     unsigned int i, nget = pollcb->nalloc;
 
-    if (timeout < 0) {
-        tvptr = NULL;
-    }
-    else {
-        tv.tv_sec = (long) apr_time_sec(timeout);
-        tv.tv_nsec = (long) apr_time_usec(timeout) * 1000;
-        tvptr = &tv;
-    }
+    rv = call_port_getn(pollcb->port_fd, pollcb->port_set, pollcb->nalloc,
+                        &nget, timeout);
 
-    ret = port_getn(pollcb->port_fd, pollcb->port_set, pollcb->nalloc,
-                    &nget, tvptr);
-
-    if (ret == -1) {
-        if (errno == ETIME) {
-            rv = APR_TIMEUP;
-        }
-        else {
-            rv = apr_get_netos_error();
-        }
-    }
-    else if (nget == 0) {
-        rv = APR_TIMEUP;
-    }
-    else {
+    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);



Mime
View raw message