summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbrianp <brianp@13f79535-47bb-0310-9956-ffa450edef68>2005-11-27 02:11:42 +0000
committerbrianp <brianp@13f79535-47bb-0310-9956-ffa450edef68>2005-11-27 02:11:42 +0000
commit52efe216e552f4053601234255782e052240c9d7 (patch)
tree2fdad49c0cbd7211c34ef315ef339c7a21e6962a
parent5b089cc775866abe078b69ed4f15f500c0799b8c (diff)
downloadlibapr-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--CHANGES5
-rw-r--r--poll/unix/select.c5
-rw-r--r--test/testpoll.c38
3 files changed, 48 insertions, 0 deletions
diff --git a/CHANGES b/CHANGES
index 68a4371a1..ff966a32b 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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);