changeset 6131:23e21b08db78

7191587: (se) SelectionKey.interestOps does not defer changing the interest set to the next select [macosx] Reviewed-by: alanb Contributed-by: Jason T Greene <jason.greene@redhat.com>
author alanb
date Thu, 23 Aug 2012 13:07:08 +0100
parents 770fc16ac677
children a054541fa782
files src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java
diffstat 2 files changed, 48 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java	Fri Aug 31 13:42:47 2012 +0100
+++ b/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java	Thu Aug 23 13:07:08 2012 +0100
@@ -34,7 +34,8 @@
 import sun.misc.*;
 import java.io.IOException;
 import java.io.FileDescriptor;
-
+import java.util.Iterator;
+import java.util.LinkedList;
 
 /*
  * struct kevent {           // 32-bit    64-bit
@@ -99,6 +100,18 @@
         kq = init();
     }
 
+    // Used to update file description registrations
+    private static class Update {
+        SelChImpl channel;
+        int events;
+        Update(SelChImpl channel, int events) {
+            this.channel = channel;
+            this.events = events;
+        }
+    }
+
+    private LinkedList<Update> updateList = new LinkedList<Update>();
+
     void initInterrupt(int fd0, int fd1) {
         outgoingInterruptFD = fd1;
         incomingInterruptFD = fd0;
@@ -136,14 +149,41 @@
         }
     }
 
-    void setInterest(int fd, int events) {
-        register0(kq, fd, events & POLLIN, events & POLLOUT);
+    void setInterest(SelChImpl channel, int events) {
+        synchronized (updateList) {
+            // update existing registration
+            updateList.add(new Update(channel, events));
+        }
     }
 
-    void release(int fd) {
-        register0(kq, fd, 0, 0);
+    void release(SelChImpl channel) {
+        synchronized (updateList) {
+            // flush any pending updates
+            for (Iterator<Update> it = updateList.iterator(); it.hasNext();) {
+                if (it.next().channel == channel) {
+                    it.remove();
+                }
+            }
+
+            // remove
+            register0(kq, channel.getFDVal(), 0, 0);
+        }
     }
 
+    void updateRegistrations() {
+        synchronized (updateList) {
+            Update u = null;
+            while ((u = updateList.poll()) != null) {
+                SelChImpl ch = u.channel;
+                if (!ch.isOpen())
+                    continue;
+
+                register0(kq, ch.getFDVal(), u.events & POLLIN, u.events & POLLOUT);
+            }
+        }
+    }
+
+
     void close() throws IOException {
         if (keventArray != null) {
             keventArray.free();
@@ -156,6 +196,7 @@
     }
 
     int poll(long timeout) {
+        updateRegistrations();
         int updated = kevent0(kq, keventArrayAddress, NUM_KEVENTS, timeout);
         return updated;
     }
@@ -172,4 +213,3 @@
                                long timeout);
     private static native void interrupt(int fd);
 }
-
--- a/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java	Fri Aug 31 13:42:47 2012 +0100
+++ b/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java	Thu Aug 23 13:07:08 2012 +0100
@@ -184,7 +184,6 @@
             FileDispatcherImpl.closeIntFD(fd0);
             FileDispatcherImpl.closeIntFD(fd1);
             if (kqueueWrapper != null) {
-                kqueueWrapper.release(fd0);
                 kqueueWrapper.close();
                 kqueueWrapper = null;
                 selectedKeys = null;
@@ -220,7 +219,7 @@
     protected void implDereg(SelectionKeyImpl ski) throws IOException {
         int fd = ski.channel.getFDVal();
         fdMap.remove(Integer.valueOf(fd));
-        kqueueWrapper.release(fd);
+        kqueueWrapper.release(ski.channel);
         totalChannels--;
         keys.remove(ski);
         selectedKeys.remove(ski);
@@ -234,8 +233,7 @@
     public void putEventOps(SelectionKeyImpl ski, int ops) {
         if (closed)
             throw new ClosedSelectorException();
-        int fd = IOUtil.fdVal(ski.channel.getFD());
-        kqueueWrapper.setInterest(fd, ops);
+        kqueueWrapper.setInterest(ski.channel, ops);
     }
 
 
@@ -254,4 +252,3 @@
         Util.load();
     }
 }
-