diff options
author | brianp <brianp@13f79535-47bb-0310-9956-ffa450edef68> | 2005-11-27 02:11:42 +0000 |
---|---|---|
committer | brianp <brianp@13f79535-47bb-0310-9956-ffa450edef68> | 2005-11-27 02:11:42 +0000 |
commit | 52efe216e552f4053601234255782e052240c9d7 (patch) | |
tree | 2fdad49c0cbd7211c34ef315ef339c7a21e6962a | |
parent | 5b089cc775866abe078b69ed4f15f500c0799b8c (diff) | |
download | libapr-52efe216e552f4053601234255782e052240c9d7.tar.gz |
Properly compute number of signalled descriptors in apr_poll()
and apr_pollset_poll() if one or more of them are both readable
and writable. [Backport of svn revisions 348499 and 349070
from APR development trunk]
git-svn-id: http://svn.apache.org/repos/asf/apr/apr/branches/1.2.x@349169 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r-- | CHANGES | 5 | ||||
-rw-r--r-- | poll/unix/select.c | 5 | ||||
-rw-r--r-- | test/testpoll.c | 38 |
3 files changed, 48 insertions, 0 deletions
@@ -1,5 +1,10 @@ Changes for APR 1.2.3-dev + *) Bugfix for apr_pollset_poll() on systems that implement pollsets + using select(2): properly compute the number of signalled desciptors + when one or more of them are both readable and writable. + [Dror Shilo <Dror.Shilo ericom.com>, Gerry <gerry everythingsucks.co.uk>] + *) Fix apr_file_seek() to catch write failures when flushing pending writes for a buffered file. [Joe Orton] diff --git a/poll/unix/select.c b/poll/unix/select.c index d9212b007..a64ddbad9 100644 --- a/poll/unix/select.c +++ b/poll/unix/select.c @@ -131,6 +131,7 @@ APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, int num, return apr_get_netos_error(); } + (*nsds) = 0; for (i = 0; i < num; i++) { apr_os_sock_t fd; @@ -156,6 +157,9 @@ APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, int num, if (FD_ISSET(fd, &exceptset)) { aprset[i].rtnevents |= APR_POLLERR; } + if (aprset[i].rtnevents) { + (*nsds)++; + } } return APR_SUCCESS; @@ -395,6 +399,7 @@ APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset, j++; } } + (*num) = j; if (descriptors) *descriptors = pollset->result_set; diff --git a/test/testpoll.c b/test/testpoll.c index ebcb8acd9..351dcce78 100644 --- a/test/testpoll.c +++ b/test/testpoll.c @@ -290,6 +290,43 @@ static void setup_pollset(abts_case *tc, void *data) ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); } +static void multi_event_pollset(abts_case *tc, void *data) +{ + apr_status_t rv; + apr_pollfd_t socket_pollfd; + int lrv; + const apr_pollfd_t *descs = NULL; + + ABTS_PTR_NOTNULL(tc, s[0]); + socket_pollfd.desc_type = APR_POLL_SOCKET; + socket_pollfd.reqevents = APR_POLLIN | APR_POLLOUT; + socket_pollfd.desc.s = s[0]; + socket_pollfd.client_data = s[0]; + rv = apr_pollset_add(pollset, &socket_pollfd); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + send_msg(s, sa, 0, tc); + + rv = apr_pollset_poll(pollset, 0, &lrv, &descs); + ABTS_INT_EQUAL(tc, 0, APR_STATUS_IS_TIMEUP(rv)); + ABTS_INT_EQUAL(tc, 1, lrv); + ABTS_PTR_EQUAL(tc, s[0], descs[0].desc.s); + ABTS_INT_EQUAL(tc, APR_POLLIN | APR_POLLOUT, descs[0].rtnevents); + ABTS_PTR_EQUAL(tc, s[0], descs[0].client_data); + + recv_msg(s, 0, p, tc); + + rv = apr_pollset_poll(pollset, 0, &lrv, &descs); + ABTS_INT_EQUAL(tc, 0, APR_STATUS_IS_TIMEUP(rv)); + ABTS_INT_EQUAL(tc, 1, lrv); + ABTS_PTR_EQUAL(tc, s[0], descs[0].desc.s); + ABTS_INT_EQUAL(tc, APR_POLLOUT, descs[0].rtnevents); + ABTS_PTR_EQUAL(tc, s[0], descs[0].client_data); + + rv = apr_pollset_remove(pollset, &socket_pollfd); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); +} + static void add_sockets_pollset(abts_case *tc, void *data) { apr_status_t rv; @@ -520,6 +557,7 @@ abts_suite *testpoll(abts_suite *suite) #endif abts_run_test(suite, setup_pollset, NULL); + abts_run_test(suite, multi_event_pollset, NULL); abts_run_test(suite, add_sockets_pollset, NULL); abts_run_test(suite, nomessage_pollset, NULL); abts_run_test(suite, send0_pollset, NULL); |