Here is another little fix for the epoll selector, which deals with the
epoll man pages not being exactly clear on what error values it returns.

I've been able to run Azureus, unmodified, on Ubuntu GNU/Linux with
jamvm! Even running on jamvm, it's really snappy.

The kqueue selector doesn't quite work as well, yet, but I'm looking at
this now.

2006-09-22  Casey Marshall  <[EMAIL PROTECTED]>

        * gnu/java/nio/EpollSelectorImpl.java (doSelect): remove keys
        after we delete them.
        (selectedKeys): return an empty set if nothing's been selected.
        * native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c
        (Java_gnu_java_nio_EpollSelectorImpl_epoll_1delete): don't
        throw an exception on EBADF.
        (Java_gnu_java_nio_EpollSelectorImpl_epoll_1wait): don't
        throw exception on EINTR, just return 0.

Have fun.
### Eclipse Workspace Patch 1.0
#P classpath
Index: gnu/java/nio/EpollSelectorImpl.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/nio/EpollSelectorImpl.java,v
retrieving revision 1.2
diff -u -r1.2 EpollSelectorImpl.java
--- gnu/java/nio/EpollSelectorImpl.java 21 Sep 2006 23:23:02 -0000      1.2
+++ gnu/java/nio/EpollSelectorImpl.java 23 Sep 2006 06:39:20 -0000
@@ -139,6 +139,7 @@
             epoll_delete(epoll_fd, key.fd);
             key.valid = false;
             keys.remove(new Integer(key.fd));
+            it.remove();
           }
         
         // Don't bother if we have nothing to select.
@@ -177,6 +178,8 @@
    */
   public Set selectedKeys()
   {
+    if (selectedKeys == null)
+      return Collections.EMPTY_SET;
     return selectedKeys;
   }
 
Index: native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c
===================================================================
RCS file: 
/cvsroot/classpath/classpath/native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c,v
retrieving revision 1.2
diff -u -r1.2 gnu_java_nio_EpollSelectorImpl.c
--- native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c        20 Sep 2006 
22:28:08 -0000      1.2
+++ native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c        23 Sep 2006 
06:39:20 -0000
@@ -150,8 +150,8 @@
   event.data.fd = fd;
 
 #ifdef TRACE_EPOLL
-  fprintf (stderr, "%s: adding struct epoll_event { events: %o; data.fd: %d 
}\n",
-           __FUNCTION__, event.events, event.data.fd);
+  fprintf (stderr, "%s: adding struct epoll_event { events: %o; data.fd: %d } 
to %d\n",
+           __FUNCTION__, event.events, event.data.fd, efd);
 #endif /* TRACE_EPOLL */
 
   if (epoll_ctl (efd, EPOLL_CTL_ADD, fd, &event) == -1)
@@ -197,8 +197,8 @@
   event.data.fd = fd;
 
 #ifdef TRACE_EPOLL
-  fprintf (stderr, "%s: modding struct epoll_event { events: %o; data.fd: %d 
}\n",
-           __FUNCTION__, event.events, event.data.fd);
+  fprintf (stderr, "%s: modding struct epoll_event { events: %o; data.fd: %d } 
on %d\n",
+           __FUNCTION__, event.events, event.data.fd, efd);
 #endif /* TRACE_EPOLL */
 
   if (epoll_ctl (efd, EPOLL_CTL_MOD, fd, &event) == -1)
@@ -235,7 +235,7 @@
   event.data.fd = fd;
 
 #ifdef TRACE_EPOLL
-  fprintf (stderr, "%s: delete events on fd %d\n", __FUNCTION__, fd);
+  fprintf (stderr, "%s: delete events on fd %d for %d\n", __FUNCTION__, fd, 
efd);
 #endif /* TRACE_EPOLL */
 
   /* Older kernel versions require a non-null `event' parameter,
@@ -246,7 +246,11 @@
       if (ENOSYS == errno)
         JCL_ThrowException (env, "java/lang/InternalError",
                             strerror (errno));
-      else if (ENOENT == errno)
+      /* XXX the docs here seem a little strange. If `fd' is closed,
+         epoll_ctl returns EBADF; but the docs say that this happens
+         only when efd is invalid. Go figure.
+       */
+      else if (ENOENT == errno || EBADF == errno)
         return; /* fd is closed; it's already removed. */
       else
         JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
@@ -282,16 +286,19 @@
     }
 
 #ifdef TRACE_EPOLL
-  fprintf (stderr, "%s: events: %p; num_events: %d; timeout: %d\n",
-           __FUNCTION__, p, num_events, timeout);
+  fprintf (stderr, "%s: events: %p; num_events: %d; timeout: %d; efd: %d\n",
+           __FUNCTION__, p, num_events, timeout, efd);
 #endif /* TRACE_EPOLL */
 
   ret = epoll_wait (efd, events, num_events, timeout);
+
   if (ret == -1)
     {
       if (ENOSYS == errno)
         JCL_ThrowException (env, "java/lang/InternalError",
                             strerror (errno));
+      else if (EINTR == errno)
+        ret = 0;
       else
         JCL_ThrowException (env, IO_EXCEPTION, strerror (errno));
     }
Index: ChangeLog
===================================================================
RCS file: /cvsroot/classpath/classpath/ChangeLog,v
retrieving revision 1.8600
diff -u -r1.8600 ChangeLog
--- ChangeLog   23 Sep 2006 05:17:45 -0000      1.8600
+++ ChangeLog   23 Sep 2006 06:39:20 -0000
@@ -1,5 +1,16 @@
 2006-09-22  Casey Marshall  <[EMAIL PROTECTED]>
 
+       * gnu/java/nio/EpollSelectorImpl.java (doSelect): remove keys
+       after we delete them.
+       (selectedKeys): return an empty set if nothing's been selected.
+       * native/jni/java-nio/gnu_java_nio_EpollSelectorImpl.c
+       (Java_gnu_java_nio_EpollSelectorImpl_epoll_1delete): don't
+       throw an exception on EBADF.
+       (Java_gnu_java_nio_EpollSelectorImpl_epoll_1wait): don't
+       throw exception on EINTR, just return 0.
+       
+2006-09-22  Casey Marshall  <[EMAIL PROTECTED]>
+
        * native/jni/java-io/java_io_VMFile.c (Java_java_io_VMFile_list):
        remove `const' from `filename.'
        * native/jni/native-lib/cpio.c (cpio_readDir): remove `const' from

Reply via email to