diff --git a/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java b/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java index 7ec35f1bc6d669fe0f3007dbc4348940456d51b2..f83fe3fd83b42ac2163b8ea4c5590eaeaa739336 100644 --- a/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java +++ b/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java @@ -34,7 +34,8 @@ package sun.nio.ch; 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 @@ -100,6 +101,18 @@ class KQueueArrayWrapper { 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 updateList = new LinkedList(); + void initInterrupt(int fd0, int fd1) { outgoingInterruptFD = fd1; incomingInterruptFD = fd0; @@ -137,14 +150,41 @@ class KQueueArrayWrapper { } } - 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 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(); @@ -157,6 +197,7 @@ class KQueueArrayWrapper { } int poll(long timeout) { + updateRegistrations(); int updated = kevent0(kq, keventArrayAddress, NUM_KEVENTS, timeout); return updated; } @@ -173,4 +214,3 @@ class KQueueArrayWrapper { long timeout); private static native void interrupt(int fd); } - diff --git a/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java b/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java index b1504264474187c2e76a59b4fbcb6893fe801bce..7639ef08a07a40a525746c7d516c988f3ea2740f 100644 --- a/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java +++ b/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java @@ -184,7 +184,6 @@ class KQueueSelectorImpl FileDispatcherImpl.closeIntFD(fd0); FileDispatcherImpl.closeIntFD(fd1); if (kqueueWrapper != null) { - kqueueWrapper.release(fd0); kqueueWrapper.close(); kqueueWrapper = null; selectedKeys = null; @@ -220,7 +219,7 @@ class KQueueSelectorImpl 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 @@ class KQueueSelectorImpl 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 @@ class KQueueSelectorImpl Util.load(); } } -