提交 5e5014d2 编写于 作者: A alanb

7191587: (se) SelectionKey.interestOps does not defer changing the interest...

7191587: (se) SelectionKey.interestOps does not defer changing the interest set to the next select [macosx]
Reviewed-by: alanb
Contributed-by: NJason T Greene <jason.greene@redhat.com>
上级 8f0d4782
...@@ -34,7 +34,8 @@ package sun.nio.ch; ...@@ -34,7 +34,8 @@ package sun.nio.ch;
import sun.misc.*; import sun.misc.*;
import java.io.IOException; import java.io.IOException;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.util.Iterator;
import java.util.LinkedList;
/* /*
* struct kevent { // 32-bit 64-bit * struct kevent { // 32-bit 64-bit
...@@ -100,6 +101,18 @@ class KQueueArrayWrapper { ...@@ -100,6 +101,18 @@ class KQueueArrayWrapper {
kq = init(); 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) { void initInterrupt(int fd0, int fd1) {
outgoingInterruptFD = fd1; outgoingInterruptFD = fd1;
incomingInterruptFD = fd0; incomingInterruptFD = fd0;
...@@ -137,14 +150,41 @@ class KQueueArrayWrapper { ...@@ -137,14 +150,41 @@ class KQueueArrayWrapper {
} }
} }
void setInterest(int fd, int events) { void setInterest(SelChImpl channel, int events) {
register0(kq, fd, events & POLLIN, events & POLLOUT); synchronized (updateList) {
// update existing registration
updateList.add(new Update(channel, events));
}
} }
void release(int fd) { void release(SelChImpl channel) {
register0(kq, fd, 0, 0); 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 { void close() throws IOException {
if (keventArray != null) { if (keventArray != null) {
keventArray.free(); keventArray.free();
...@@ -157,6 +197,7 @@ class KQueueArrayWrapper { ...@@ -157,6 +197,7 @@ class KQueueArrayWrapper {
} }
int poll(long timeout) { int poll(long timeout) {
updateRegistrations();
int updated = kevent0(kq, keventArrayAddress, NUM_KEVENTS, timeout); int updated = kevent0(kq, keventArrayAddress, NUM_KEVENTS, timeout);
return updated; return updated;
} }
...@@ -173,4 +214,3 @@ class KQueueArrayWrapper { ...@@ -173,4 +214,3 @@ class KQueueArrayWrapper {
long timeout); long timeout);
private static native void interrupt(int fd); private static native void interrupt(int fd);
} }
...@@ -184,7 +184,6 @@ class KQueueSelectorImpl ...@@ -184,7 +184,6 @@ class KQueueSelectorImpl
FileDispatcherImpl.closeIntFD(fd0); FileDispatcherImpl.closeIntFD(fd0);
FileDispatcherImpl.closeIntFD(fd1); FileDispatcherImpl.closeIntFD(fd1);
if (kqueueWrapper != null) { if (kqueueWrapper != null) {
kqueueWrapper.release(fd0);
kqueueWrapper.close(); kqueueWrapper.close();
kqueueWrapper = null; kqueueWrapper = null;
selectedKeys = null; selectedKeys = null;
...@@ -220,7 +219,7 @@ class KQueueSelectorImpl ...@@ -220,7 +219,7 @@ class KQueueSelectorImpl
protected void implDereg(SelectionKeyImpl ski) throws IOException { protected void implDereg(SelectionKeyImpl ski) throws IOException {
int fd = ski.channel.getFDVal(); int fd = ski.channel.getFDVal();
fdMap.remove(Integer.valueOf(fd)); fdMap.remove(Integer.valueOf(fd));
kqueueWrapper.release(fd); kqueueWrapper.release(ski.channel);
totalChannels--; totalChannels--;
keys.remove(ski); keys.remove(ski);
selectedKeys.remove(ski); selectedKeys.remove(ski);
...@@ -234,8 +233,7 @@ class KQueueSelectorImpl ...@@ -234,8 +233,7 @@ class KQueueSelectorImpl
public void putEventOps(SelectionKeyImpl ski, int ops) { public void putEventOps(SelectionKeyImpl ski, int ops) {
if (closed) if (closed)
throw new ClosedSelectorException(); throw new ClosedSelectorException();
int fd = IOUtil.fdVal(ski.channel.getFD()); kqueueWrapper.setInterest(ski.channel, ops);
kqueueWrapper.setInterest(fd, ops);
} }
...@@ -254,4 +252,3 @@ class KQueueSelectorImpl ...@@ -254,4 +252,3 @@ class KQueueSelectorImpl
Util.load(); Util.load();
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册