The attached patch removes the double for() loops in both the KQueue
and epoll _poll() implementations.  Both epoll and kqueue have a method
for associating arbitrary user data with the event.  This patch uses
these to store the key to an event's location in the query_set array.

        I also had to change testpoll.c again because the kqueue and epoll
implementations will return their result set with a different order (but
the same sockets will still come..)

Thanks,

-Paul Querna   

Index: poll/unix/poll.c
===================================================================
RCS file: /home/cvspublic/apr/poll/unix/poll.c,v
retrieving revision 1.46
diff -u -r1.46 poll.c
--- poll/unix/poll.c	7 Jul 2004 07:40:12 -0000	1.46
+++ poll/unix/poll.c	18 Jul 2004 21:30:31 -0000
@@ -471,7 +471,8 @@
     }
 
     if (descriptor->reqevents & APR_POLLIN) {
-        EV_SET(&pollset->kevent, fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
+        EV_SET(&pollset->kevent, fd, EVFILT_READ, EV_ADD, 0, 0, 
+            (void*)pollset->nelts);
 
         if (kevent(pollset->kqueue_fd, &pollset->kevent, 1, NULL, 0,
                    NULL) == -1) {
@@ -480,7 +481,8 @@
     }
 
     if (descriptor->reqevents & APR_POLLOUT) {
-        EV_SET(&pollset->kevent, fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL);
+        EV_SET(&pollset->kevent, fd, EVFILT_WRITE, EV_ADD, 0, 0, 
+            (void*)pollset->nelts);
 
         if (kevent(pollset->kqueue_fd, &pollset->kevent, 1, NULL, 0,
                    NULL) == -1) {
@@ -490,16 +492,16 @@
 
 #elif defined(HAVE_EPOLL)
     ev.events = get_epoll_event(descriptor->reqevents);
+    ev.data.fd = pollset->nelts;
     if (descriptor->desc_type == APR_POLL_SOCKET) {
-        ev.data.fd = descriptor->desc.s->socketdes;
         ret = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_ADD,
                         descriptor->desc.s->socketdes, &ev);
     }
     else {
-        ev.data.fd = descriptor->desc.f->filedes;
         ret = epoll_ctl(pollset->epoll_fd, EPOLL_CTL_ADD,
                         descriptor->desc.f->filedes, &ev);
     }
+
     if (0 != ret) {
         return APR_EBADF;
     }
@@ -723,14 +725,15 @@
 
     return APR_NOTFOUND;
 }
+
 #ifdef HAVE_KQUEUE
+
 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, r = 0;
+    int rv, i, r;
     struct timespec tv, *tvptr;
 
     if (timeout < 0) {
@@ -752,28 +755,16 @@
         return APR_TIMEUP;
     }
 
-    /* TODO: Is there a better way to re-associate our data? */
-    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 {
-            fd = pollset->query_set[i].desc.f->filedes;
-        }
-        for (j = 0; j < rv; j++) {
-            if (pollset->ke_set[j].ident == fd ) {
-                pollset->result_set[r] = pollset->query_set[i];
-                pollset->result_set[r].rtnevents =
-                    get_kqueue_revent(pollset->ke_set[j].filter,
-                                      pollset->ke_set[j].flags);
-                r++;
-            }
-        }
+    r = 0;
+    for (i = 0; i < rv; i++) {
+        pollset->result_set[r] = 
+            pollset->query_set[((int)pollset->ke_set[i].udata)];
+        pollset->result_set[r].rtnevents = 
+            get_kqueue_revent(pollset->ke_set[i].filter,
+                              pollset->ke_set[i].flags);
+        r++;
     }
 
-    (*num) = r;
-
     if (descriptors) {
         *descriptors = pollset->result_set;
     }
@@ -788,8 +779,7 @@
                                            apr_int32_t *num,
                                            const apr_pollfd_t **descriptors)
 {
-    int rv;
-    apr_uint32_t i, j, k;
+    int rv, i, r;
 
     if (timeout > 0) {
         timeout /= 1000;
@@ -804,38 +794,24 @@
     if (rv == 0) {
         return APR_TIMEUP;
     }
-    j = 0;
-    for (i = 0; i < pollset->nelts; i++) {
-        if (pollset->pollset[i].events != 0) {
-            /* TODO: Is there a better way to re-associate our data? */
-            for (k = 0; k < pollset->nelts; k++) {
-                if (pollset->query_set[k].desc_type == APR_POLL_SOCKET &&
-                    pollset->query_set[k].desc.s->socketdes ==
-                        pollset->pollset[i].data.fd) {
-                    pollset->result_set[j] = pollset->query_set[k];
-                    pollset->result_set[j].rtnevents =
-                        get_epoll_revent(pollset->pollset[i].events);
-                    j++;
-                    break;
-                }
-                else if (pollset->query_set[k].desc_type == APR_POLL_FILE 
-                         && pollset->query_set[k].desc.f->filedes ==
-                            pollset->pollset[i].data.fd) {
-                    pollset->result_set[j] = pollset->query_set[k];
-                    pollset->result_set[j].rtnevents =
-                        get_epoll_revent(pollset->pollset[i].events);
-                    j++;
-                    break;
-                }
-            }
-        }
+
+    r = 0;
+    for (i = 0; i < rv; i++) {
+        pollset->result_set[r] = 
+            pollset->query_set[pollset->pollset[i].data.fd];
+        pollset->result_set[r].rtnevents =
+            get_epoll_revent(pollset->pollset[i].events);
+        r++;
     }
+
     if (descriptors) {
         *descriptors = pollset->result_set;
     }
     return APR_SUCCESS;
 }
+
 #elif defined(HAVE_POLL)
+
 APR_DECLARE(apr_status_t) apr_pollset_poll(apr_pollset_t *pollset,
                                            apr_interval_time_t timeout,
                                            apr_int32_t *num,
Index: test/testpoll.c
===================================================================
RCS file: /home/cvspublic/apr/test/testpoll.c,v
retrieving revision 1.34
diff -u -r1.34 testpoll.c
--- test/testpoll.c	6 Jul 2004 03:38:06 -0000	1.34
+++ test/testpoll.c	18 Jul 2004 21:30:32 -0000
@@ -426,6 +426,7 @@
 static void pollset_remove(abts_case *tc, void *data)
 {
     apr_status_t rv;
+    int i, c;
     apr_pollset_t *pollset;
     const apr_pollfd_t *hot_files;
     apr_pollfd_t pfd;
@@ -472,13 +473,29 @@
     rv = apr_pollset_poll(pollset, 1000, &num, &hot_files);
     ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
     ABTS_INT_EQUAL(tc, 3, num);
-    ABTS_PTR_EQUAL(tc, (void *)1, hot_files[0].client_data);
-    ABTS_PTR_EQUAL(tc, s[0], hot_files[0].desc.s);
-    ABTS_PTR_EQUAL(tc, (void *)3, hot_files[1].client_data);
-    ABTS_PTR_EQUAL(tc, s[2], hot_files[1].desc.s);
-    ABTS_PTR_EQUAL(tc, (void *)4, hot_files[2].client_data);
-    ABTS_PTR_EQUAL(tc, s[3], hot_files[2].desc.s);
-    
+
+    for(i = 0, c = 0; i < num; i++) {
+        if(hot_files[i].client_data == (void*)1) {
+            ABTS_PTR_EQUAL(tc, (void *)1, hot_files[i].client_data);
+            ABTS_PTR_EQUAL(tc, s[0], hot_files[i].desc.s);
+            c++;
+        }
+        else if(hot_files[i].client_data == (void*)3) {
+            ABTS_PTR_EQUAL(tc, (void *)3, hot_files[i].client_data);
+            ABTS_PTR_EQUAL(tc, s[2], hot_files[i].desc.s);
+            c++;
+        }
+        else if(hot_files[i].client_data == (void*)4) {
+            ABTS_PTR_EQUAL(tc, (void *)4, hot_files[i].client_data);
+            ABTS_PTR_EQUAL(tc, s[3], hot_files[1].desc.s);
+            c++;
+        }
+        else {
+            ABTS_ASSERT(tc, "Client Data is Invalid.", 1);
+        }
+    }
+    ABTS_INT_EQUAL(tc, c, num);
+
     /* now remove the pollset elements referring to desc s[2] */
     pfd.desc.s = s[2];
     pfd.client_data = (void *)999; /* not used on this call */

Reply via email to