summaryrefslogtreecommitdiff
path: root/poll/unix
diff options
context:
space:
mode:
authorBrian Pane <brianp@apache.org>2002-08-07 00:06:12 +0000
committerBrian Pane <brianp@apache.org>2002-08-07 00:06:12 +0000
commitaf9ad622a5467e7e164aaf1a500e5e9c83156cd7 (patch)
tree83dcc4e9965cde2228e8aecded155a4435650abf /poll/unix
parentc73892daa812fed397635440386b6b943684329a (diff)
downloadapr-af9ad622a5467e7e164aaf1a500e5e9c83156cd7.tar.gz
Changed apr_poll_socket_remove() and apr_poll() to avoid
putting invalid descriptors on the pollset after removing from the middle of the array Reported by: Rob Saccoccio <robs@fastcgi.com> git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@63801 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'poll/unix')
-rw-r--r--poll/unix/poll.c10
-rw-r--r--poll/unix/pollacc.c21
2 files changed, 28 insertions, 3 deletions
diff --git a/poll/unix/poll.c b/poll/unix/poll.c
index f495c821f..da79e4b95 100644
--- a/poll/unix/poll.c
+++ b/poll/unix/poll.c
@@ -151,6 +151,10 @@ APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, apr_int32_t num,
else if (aprset[i].desc_type == APR_POLL_FILE) {
pollset[i].fd = aprset[i].desc.f->filedes;
}
+ else if (aprset[i].desc_type == APR_NO_DESC) {
+ num = i + 1;
+ break;
+ }
pollset[i].events = get_event(aprset[i].reqevents);
}
@@ -221,7 +225,7 @@ APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, int num, apr_int32_t *n
#endif
fd = aprset[i].desc.s->socketdes;
}
- else {
+ else if (aprset[i].desc_type == APR_POLL_FILE) {
#if !APR_FILES_AS_SOCKETS
return APR_EBADF;
#else
@@ -237,6 +241,10 @@ APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, int num, apr_int32_t *n
#endif /* APR_FILES_AS_SOCKETS */
}
+ else if (aprset[i].desc_type == APR_NO_DESC) {
+ num = i + 1;
+ break;
+ }
if (aprset[i].reqevents & APR_POLLIN) {
FD_SET(fd, &readset);
}
diff --git a/poll/unix/pollacc.c b/poll/unix/pollacc.c
index d421a45c0..36a2c8c7c 100644
--- a/poll/unix/pollacc.c
+++ b/poll/unix/pollacc.c
@@ -134,11 +134,28 @@ APR_DECLARE(apr_status_t) apr_poll_socket_mask(apr_pollfd_t *aprset,
APR_DECLARE(apr_status_t) apr_poll_socket_remove(apr_pollfd_t *aprset, apr_socket_t *sock)
{
- apr_pollfd_t *curr = find_poll_sock(aprset, sock);
- if (curr == NULL) {
+ apr_pollfd_t *match = NULL;
+ apr_pollfd_t *curr;
+
+ for (curr = aprset; (curr->desc_type != APR_POLL_LASTDESC) &&
+ (curr->desc_type != APR_NO_DESC); curr++) {
+ if (curr->desc.s == sock) {
+ match = curr;
+ }
+ }
+ if (match == NULL) {
return APR_NOTFOUND;
}
+ /* Remove this entry by swapping the last entry into its place.
+ * This ensures that the non-APR_NO_DESC entries are all at the
+ * start of the array, so that apr_poll() doesn't have to worry
+ * about invalid entries in the middle of the pollset.
+ */
+ curr--;
+ if (curr != match) {
+ *match = *curr;
+ }
curr->desc_type = APR_NO_DESC;
return APR_SUCCESS;