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>
--- a/jdk/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java Thu Aug 23 16:28:17 2012 +0800
+++ b/jdk/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
@@ -100,6 +101,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;
@@ -137,14 +150,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();
@@ -157,6 +197,7 @@
}
int poll(long timeout) {
+ updateRegistrations();
int updated = kevent0(kq, keventArrayAddress, NUM_KEVENTS, timeout);
return updated;
}
@@ -173,4 +214,3 @@
long timeout);
private static native void interrupt(int fd);
}
-
--- a/jdk/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java Thu Aug 23 16:28:17 2012 +0800
+++ b/jdk/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();
}
}
-