Attached is a patch that *might* fix PR 29190. I don't have a Linux
system to test this on anymore :-(, so this may not work.

The issue was really that the epoll selector (and the kqueue selector,
now that I think about it) doesn't use the SPI interface correctly,
meaning that de-registering and canceling keys doesn't work quite right.
### 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.3
diff -u -r1.3 EpollSelectorImpl.java
--- gnu/java/nio/EpollSelectorImpl.java 23 Sep 2006 06:44:13 -0000      1.3
+++ gnu/java/nio/EpollSelectorImpl.java 24 Sep 2006 03:51:10 -0000
@@ -75,7 +75,6 @@
   
   private final HashMap keys;
   private Set selectedKeys;
-  private final Set cancelledKeys;
   private Thread waitingThread;
 
   static
@@ -96,7 +95,6 @@
     epoll_fd = epoll_create(DEFAULT_EPOLL_SIZE);
     keys = new HashMap();
     selectedKeys = null;
-    cancelledKeys = new HashSet();
   }
 
   /* (non-Javadoc)
@@ -131,6 +129,7 @@
   {
     synchronized (keys)
     {
+      Set cancelledKeys = cancelledKeys();
       synchronized (cancelledKeys)
       {
         for (Iterator it = cancelledKeys.iterator(); it.hasNext(); )
@@ -140,6 +139,7 @@
             key.valid = false;
             keys.remove(new Integer(key.fd));
             it.remove();
+            deregister(key);
           }
         
         // Don't bother if we have nothing to select.
@@ -149,10 +149,19 @@
         ByteBuffer selected =
           ByteBuffer.allocateDirect(keys.size() * sizeof_struct_epoll_event);
       
-        waitingThread = Thread.currentThread();
-        int ret = epoll_wait(epoll_fd, selected, keys.size(), timeout);
-        Thread.interrupted();
-        waitingThread = null;
+        int ret;
+        try
+          {
+            begin();
+            waitingThread = Thread.currentThread();
+            ret = epoll_wait(epoll_fd, selected, keys.size(), timeout);
+          }
+        finally
+          {
+            Thread.interrupted();
+            waitingThread = null;
+            end();
+          }
       
         HashSet s = new HashSet(ret);
         for (int i = 0; i < ret; i++)
@@ -255,14 +264,6 @@
     epoll_modify(epoll_fd, key.fd, ops);
   }
   
-  void cancel(EpollSelectionKeyImpl key)
-  {
-    synchronized (cancelledKeys)
-    {
-      cancelledKeys.add(key);
-    }
-  }
-  
   /**
    * Tell if epoll is supported by this system, and support was compiled in.
    *
Index: gnu/java/nio/EpollSelectionKeyImpl.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/nio/EpollSelectionKeyImpl.java,v
retrieving revision 1.1
diff -u -r1.1 EpollSelectionKeyImpl.java
--- gnu/java/nio/EpollSelectionKeyImpl.java     20 Sep 2006 21:39:41 -0000      
1.1
+++ gnu/java/nio/EpollSelectionKeyImpl.java     24 Sep 2006 03:51:10 -0000
@@ -43,11 +43,12 @@
 import java.nio.channels.SelectableChannel;
 import java.nio.channels.SelectionKey;
 import java.nio.channels.Selector;
+import java.nio.channels.spi.AbstractSelectionKey;
 
 /**
  * @author Casey Marshall ([EMAIL PROTECTED])
  */
-public class EpollSelectionKeyImpl extends SelectionKey
+public class EpollSelectionKeyImpl extends AbstractSelectionKey
 {
   final int fd;
   private final EpollSelectorImpl selector;
@@ -67,15 +68,6 @@
   }
 
   /* (non-Javadoc)
-   * @see java.nio.channels.SelectionKey#cancel()
-   */
-  public void cancel()
-  {
-    cancelled = true;
-    selector.cancel(this);
-  }
-
-  /* (non-Javadoc)
    * @see java.nio.channels.SelectionKey#channel()
    */
   public SelectableChannel channel()
@@ -113,14 +105,6 @@
   }
 
   /* (non-Javadoc)
-   * @see java.nio.channels.SelectionKey#isValid()
-   */
-  public boolean isValid()
-  {
-    return valid;
-  }
-
-  /* (non-Javadoc)
    * @see java.nio.channels.SelectionKey#readyOps()
    */
   public int readyOps()

Reply via email to