summaryrefslogtreecommitdiff
path: root/poll
diff options
context:
space:
mode:
authorJeff Trawick <trawick@apache.org>2009-08-20 12:48:14 +0000
committerJeff Trawick <trawick@apache.org>2009-08-20 12:48:14 +0000
commit11547940e9c90e9af8281db56bfb479b3fbaedd9 (patch)
tree74d7eddc2130dd4f9be14f1f313d64738632bdf3 /poll
parent40e03f9f5c1f533ab86c3dfa7b757000e9a94d09 (diff)
downloadapr-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.c107
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) {