diff options
author | Jeff Trawick <trawick@apache.org> | 2009-08-20 12:48:14 +0000 |
---|---|---|
committer | Jeff Trawick <trawick@apache.org> | 2009-08-20 12:48:14 +0000 |
commit | 11547940e9c90e9af8281db56bfb479b3fbaedd9 (patch) | |
tree | 74d7eddc2130dd4f9be14f1f313d64738632bdf3 /poll | |
parent | 40e03f9f5c1f533ab86c3dfa7b757000e9a94d09 (diff) | |
download | apr-11547940e9c90e9af8281db56bfb479b3fbaedd9.tar.gz |
backport the following relatively simple Event Port fixes from trunk:
r749049
commentary, consistency, simplification, and minor fixes
impl_pollset_create():
. return the actual port_create() failure instead of APR_ENOMEM
impl_pollset_add():
. return the actual port_associate() failure instead of APR_ENOMEM
impl_pollset_poll():
. catch port_associate() failures
. don't report returned events to caller unless something popped
besides the wakeup pipe
impl_pollcb_poll():
. fix incorrect mapping of EINTR onto APR_TIMEUP
. don't hide interesting error codes behind APR_EGENERAL
generally:
. axe redundant APR_RING_EMPTY() invocations
. don't check for EINTR explicitly, as it is handled appropriately
by the apr_get_netos_error() invocation (IOW, EINTR == APR_EINTR here)
r749490 (only the port.c portion)
pollset tweaks:
axe logic to set ignored conditions in the poll request structures
(these conditions are return-only and are always reported when
they occur)
r750279
don't lose track of a ring element when port_associate() fails
r754294 (only the port.c portion)
nelts, the number of elements in the pollset, was neither needed
nor properly maintained by these implementations, so axe the
related code
Additional, more complex fixes only in trunk at this point:
r750277, r750708, r750744
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/1.4.x@806150 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'poll')
-rw-r--r-- | poll/unix/port.c | 107 |
1 files changed, 53 insertions, 54 deletions
diff --git a/poll/unix/port.c b/poll/unix/port.c index ab45b9913..f7fd03bb1 100644 --- a/poll/unix/port.c +++ b/poll/unix/port.c @@ -30,12 +30,7 @@ static apr_int16_t get_event(apr_int16_t event) rv |= POLLPRI; if (event & APR_POLLOUT) rv |= POLLOUT; - if (event & APR_POLLERR) - rv |= POLLERR; - if (event & APR_POLLHUP) - rv |= POLLHUP; - if (event & APR_POLLNVAL) - rv |= POLLNVAL; + /* POLLERR, POLLHUP, and POLLNVAL aren't valid as requested events */ return rv; } @@ -64,7 +59,6 @@ static apr_int16_t get_revent(apr_int16_t event) struct apr_pollset_t { apr_pool_t *pool; - apr_uint32_t nelts; apr_uint32_t nalloc; int port_fd; port_event_t *port_set; @@ -78,6 +72,9 @@ struct apr_pollset_t #endif /* A ring containing all of the pollfd_t that are active */ APR_RING_HEAD(pfd_query_ring_t, pfd_elem_t) query_ring; + /* A ring containing the pollfd_t that will be added on the + * next call to apr_pollset_poll(). + */ APR_RING_HEAD(pfd_add_ring_t, pfd_elem_t) add_ring; /* A ring of pollfd_t that have been used, and then _remove'd */ APR_RING_HEAD(pfd_free_ring_t, pfd_elem_t) free_ring; @@ -169,7 +166,6 @@ APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset, size++; } (*pollset)->waiting = 0; - (*pollset)->nelts = 0; (*pollset)->nalloc = size; (*pollset)->flags = flags; (*pollset)->pool = p; @@ -179,7 +175,7 @@ APR_DECLARE(apr_status_t) apr_pollset_create(apr_pollset_t **pollset, (*pollset)->port_fd = port_create(); if ((*pollset)->port_fd < 0) { - return APR_ENOMEM; + return apr_get_netos_error(); } { @@ -246,21 +242,22 @@ APR_DECLARE(apr_status_t) apr_pollset_add(apr_pollset_t *pollset, fd = descriptor->desc.f->filedes; } + /* 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, get_event(descriptor->reqevents), (void *)elem); if (res < 0) { - rv = APR_ENOMEM; + rv = apr_get_netos_error(); APR_RING_INSERT_TAIL(&(pollset->free_ring), elem, pfd_elem_t, link); } else { - pollset->nelts++; APR_RING_INSERT_TAIL(&(pollset->query_ring), elem, pfd_elem_t, link); } } else { - pollset->nelts++; APR_RING_INSERT_TAIL(&(pollset->add_ring), elem, pfd_elem_t, link); } @@ -294,39 +291,35 @@ APR_DECLARE(apr_status_t) apr_pollset_remove(apr_pollset_t *pollset, 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), - 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), - ep, pfd_elem_t, link); - if (ENOENT == err) { - rv = APR_SUCCESS; - } - break; + for (ep = APR_RING_FIRST(&(pollset->query_ring)); + ep != APR_RING_SENTINEL(&(pollset->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), + ep, pfd_elem_t, link); + if (ENOENT == err) { + rv = APR_SUCCESS; } + break; } } - 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), - 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), - 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 (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; } + break; } } @@ -374,15 +367,24 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, fd = ep->pfd.desc.f->filedes; } - port_associate(pollset->port_fd, PORT_SOURCE_FD, - fd, get_event(ep->pfd.reqevents), ep); + ret = port_associate(pollset->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); + break; + } APR_RING_INSERT_TAIL(&(pollset->query_ring), ep, pfd_elem_t, link); - } pollset_unlock_rings(); + if (rv != APR_SUCCESS) { + apr_atomic_dec32(&pollset->waiting); + return rv; + } + ret = port_getn(pollset->port_fd, pollset->port_set, pollset->nalloc, &nget, tvptr); @@ -393,10 +395,7 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, if (ret == -1) { (*num) = 0; - if (errno == EINTR) { - rv = APR_EINTR; - } - else if (errno == ETIME) { + if (errno == ETIME) { rv = APR_TIMEUP; } else { @@ -432,17 +431,17 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, } } pollset_unlock_rings(); - if ((*num) = j) + if ((*num) = j) { /* any event besides wakeup pipe? */ rv = APR_SUCCESS; - if (descriptors) { - *descriptors = pollset->result_set; + if (descriptors) { + *descriptors = pollset->result_set; + } } } - pollset_lock_rings(); - /* Shift all PFDs in the Dead Ring to be Free Ring */ + /* Shift all PFDs in the Dead Ring to the Free Ring */ APR_RING_CONCAT(&(pollset->free_ring), &(pollset->dead_ring), pfd_elem_t, link); pollset_unlock_rings(); @@ -574,11 +573,11 @@ APR_DECLARE(apr_status_t) apr_pollcb_poll(apr_pollcb_t *pollcb, &nget, tvptr); if (ret == -1) { - if (errno == ETIME || errno == EINTR) { + if (errno == ETIME) { rv = APR_TIMEUP; } else { - rv = APR_EGENERAL; + rv = apr_get_netos_error(); } } else if (nget == 0) { |