The following patch to HEAD corrects problems with the transparent poll API.
Currently, the apr_poll_t struct is handled ambiguously WRT whether its
entries are packed or sparse. The brokeness has probably not been apparent
because in httpd entries are never removed.
The HAVE_POLL path changes are have not been compiled.
--rob
Index: poll.c
===================================================================
RCS file: /home/cvspublic/apr/poll/unix/poll.c,v
retrieving revision 1.26
diff -u -r1.26 poll.c
--- poll.c 4 Aug 2002 04:43:23 -0000 1.26
+++ poll.c 5 Aug 2002 00:36:31 -0000
@@ -117,7 +117,7 @@
APR_DECLARE(apr_status_t) apr_poll(apr_pollfd_t *aprset, apr_int32_t num,
apr_int32_t *nsds, apr_interval_time_t timeout)
{
- int i;
+ int rv, i;
#ifdef HAVE_VLA
/* XXX: I trust that this is a segv when insufficient stack exists? */
struct pollfd pollset[num];
@@ -151,6 +151,13 @@
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) {
+ pollset[i].fd = -1;
+ continue;
+ }
+ else {
+ return APR_EBADF;
+ }
pollset[i].events = get_event(aprset[i].reqevents);
}
@@ -158,11 +165,14 @@
timeout /= 1000; /* convert microseconds to milliseconds */
}
- i = poll(pollset, num, timeout);
- (*nsds) = i;
+ rv = poll(pollset, num, timeout);
- for (i = 0; i < num; i++) {
- aprset[i].rtnevents = get_revent(pollset[i].revents);
+ if (rv > 0) {
+ (*nsds) = i;
+
+ for (i = 0; i < num; i++) {
+ aprset[i].rtnevents = get_revent(pollset[i].revents);
+ }
}
#if !defined(HAVE_VLA) && !defined(HAVE_ALLOCA)
@@ -171,13 +181,13 @@
}
#endif
- if ((*nsds) < 0) {
- return apr_get_netos_error();
+ if (rv > 0) {
+ return APR_SUCCESS;
}
- if ((*nsds) == 0) {
- return APR_TIMEUP;
+ if (rv < 0) {
+ return apr_get_netos_error();
}
- return APR_SUCCESS;
+ return APR_TIMEUP;
}
@@ -221,7 +231,7 @@
#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 +247,13 @@
#endif /* APR_FILES_AS_SOCKETS */
}
+ else if (aprset[i].desc_type == APR_NO_DESC) {
+ continue;
+ }
+ else {
+ return APR_EBADF;
+ }
+
if (aprset[i].reqevents & APR_POLLIN) {
FD_SET(fd, &readset);
}
@@ -265,27 +282,32 @@
}
#endif
- (*nsds) = rv;
- if ((*nsds) == 0) {
+ if (rv == 0) {
return APR_TIMEUP;
}
- if ((*nsds) < 0) {
+ if (rv < 0) {
return apr_get_netos_error();
}
+ (*nsds) = rv;
+
for (i = 0; i < num; i++) {
apr_os_sock_t fd;
if (aprset[i].desc_type == APR_POLL_SOCKET) {
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
fd = aprset[i].desc.f->filedes;
#endif
}
+ else if (aprset[i].desc_type == APR_NO_DESC) {
+ continue;
+ }
+
aprset[i].rtnevents = 0;
if (FD_ISSET(fd, &readset)) {
aprset[i].rtnevents |= APR_POLLIN;
Index: pollacc.c
===================================================================
RCS file: /home/cvspublic/apr/poll/unix/pollacc.c,v
retrieving revision 1.2
diff -u -r1.2 pollacc.c
--- pollacc.c 16 Jul 2002 05:25:44 -0000 1.2
+++ pollacc.c 5 Aug 2002 00:36:31 -0000
@@ -77,15 +77,14 @@
static apr_pollfd_t *find_poll_sock(apr_pollfd_t *aprset, apr_socket_t
*sock)
{
apr_pollfd_t *curr = aprset;
-
- while (curr->desc.s != sock) {
- if (curr->desc_type == APR_POLL_LASTDESC) {
- return NULL;
- }
+
+ while (curr->desc_type != APR_POLL_LASTDESC) {
+ if (curr->desc.s == sock && curr->desc_type != APR_NO_DESC)
+ return curr;
curr++;
}
- return curr;
+ return NULL;
}
APR_DECLARE(apr_status_t) apr_poll_socket_add(apr_pollfd_t *aprset,