You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Dror Shilo <Dr...@ericom.com> on 2004/08/25 07:20:49 UTC

bug to fix in poll.c

the num parameter have to return the length of descriptors 

the select call returns the total number of socket handles that are ready and contained in the fd_set  structures
therefore if we have 2 socket that one have an FD_READ and the second have FD_READ and FD_WRITE it will return 3 , but the lenght of descriptors is only 2 , this is a bug 
there for the fix for this bug is to add this  line at file poll.c

(*num) = j;



#else /* no poll */

APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset,
                                           apr_interval_time_t timeout,
                                           apr_int32_t *num,
                                           const apr_pollfd_t **descriptors)
{
    int rv;
    apr_uint32_t i, j;
    struct timeval tv, *tvptr;
    fd_set readset, writeset, exceptset;

    if (timeout < 0) {
        tvptr = NULL;
    }
    else {
        tv.tv_sec = (long)apr_time_sec(timeout);
        tv.tv_usec = (long)apr_time_usec(timeout);
        tvptr = &tv;
    }

    memcpy(&readset, &(pollset->readset), sizeof(fd_set));
    memcpy(&writeset, &(pollset->writeset), sizeof(fd_set));
    memcpy(&exceptset, &(pollset->exceptset), sizeof(fd_set));

#ifdef NETWARE
    if (HAS_PIPES(pollset->set_type)) {
        rv = pipe_select(pollset->maxfd + 1, &readset, &writeset, &exceptset, tvptr);
    }
    else
#endif
    rv = select(pollset->maxfd + 1, &readset, &writeset, &exceptset, tvptr);

    (*num) = rv;
    if (rv < 0) {
        return apr_get_netos_error();
    }
    if (rv == 0) {
        return APR_TIMEUP;
    }
    j = 0;
    for (i = 0; i < pollset->nelts; i++) {
        apr_os_sock_t fd;
        if (pollset->query_set[i].desc_type == APR_POLL_SOCKET) {
            fd = pollset->query_set[i].desc.s->socketdes;
        }
        else {
#if !APR_FILES_AS_SOCKETS
            return APR_EBADF;
#else
            fd = pollset->query_set[i].desc.f->filedes;
#endif
        }
        if (FD_ISSET(fd, &readset) || FD_ISSET(fd, &writeset) ||
            FD_ISSET(fd, &exceptset)) {
            pollset->result_set[j] = pollset->query_set[i];
            pollset->result_set[j].rtnevents = 0;
            if (FD_ISSET(fd, &readset)) {
                pollset->result_set[j].rtnevents |= APR_POLLIN;
            }
            if (FD_ISSET(fd, &writeset)) {
                pollset->result_set[j].rtnevents |= APR_POLLOUT;
            }
            if (FD_ISSET(fd, &exceptset)) {
                pollset->result_set[j].rtnevents |= APR_POLLERR;
            }
            j++;
        }
    }

    if (descriptors)
        *descriptors = pollset->result_set;
	(*num) = j;
    return APR_SUCCESS;
}

#endif /* no poll */


Dror Shilo
Ericom software



Re: bug to fix in poll.c

Posted by Joe Orton <jo...@redhat.com>.
On Wed, Aug 25, 2004 at 08:20:49AM +0300, Dror Shilo wrote:
> the num parameter have to return the length of descriptors 
> 
> the select call returns the total number of socket handles that are ready and contained in the fd_set  structures
> therefore if we have 2 socket that one have an FD_READ and the second have FD_READ and FD_WRITE it will return 3 , but the lenght of descriptors is only 2 , this is a bug 
> there for the fix for this bug is to add this  line at file poll.c
> 
> (*num) = j;

Thanks for looking into this.  I don't have a platform using select() to
hand, but it looks like apr_poll() needs to be fixed too.  Can you try
this patch against 0.9.4?

--- poll/unix/poll.c	10 Apr 2004 21:29:52 -0000	1.38.2.2
+++ poll/unix/poll.c	25 Aug 2004 08:37:16 -0000
@@ -244,14 +244,14 @@
     }
 #endif
 
-    (*nsds) = rv;
-    if ((*nsds) == 0) {
+    if (rv == 0) {
         return APR_TIMEUP;
     }
-    if ((*nsds) < 0) {
+    if (rv < 0) {
         return apr_get_netos_error();
     }
-
+    
+    *nsds = 0;
     for (i = 0; i < num; i++) {
         apr_os_sock_t fd;
 
@@ -268,14 +268,18 @@
         else {
             break;
         }
-        if (FD_ISSET(fd, &readset)) {
-            aprset[i].rtnevents |= APR_POLLIN;
-        }
-        if (FD_ISSET(fd, &writeset)) {
-            aprset[i].rtnevents |= APR_POLLOUT;
-        }
-        if (FD_ISSET(fd, &exceptset)) {
-            aprset[i].rtnevents |= APR_POLLERR;
+        if (FD_ISSET(fd, &readset) || FD_ISSET(fd, &writeset) ||
+            FD_ISSET(fd, &exceptset)) {
+            (*nsds)++;
+            if (FD_ISSET(fd, &readset)) {
+                aprset[i].rtnevents |= APR_POLLIN;
+            }
+            if (FD_ISSET(fd, &writeset)) {
+                aprset[i].rtnevents |= APR_POLLOUT;
+            }
+            if (FD_ISSET(fd, &exceptset)) {
+                aprset[i].rtnevents |= APR_POLLERR;
+            }
         }
     }
 
@@ -553,8 +557,6 @@
     else
 #endif
     rv = select(pollset->maxfd + 1, &readset, &writeset, &exceptset, tvptr);
-
-    (*num) = rv;
     if (rv < 0) {
         return apr_get_netos_error();
     }
@@ -590,6 +592,8 @@
             j++;
         }
     }
+
+    (*num) = j;
 
     *descriptors = pollset->result_set;
     return APR_SUCCESS;