|
|
@ -590,32 +590,41 @@ public class Network { |
|
|
|
|
|
|
|
|
|
|
|
SelectableChannel socketChannel = nextSelectionKey.channel(); |
|
|
|
SelectableChannel socketChannel = nextSelectionKey.channel(); |
|
|
|
|
|
|
|
|
|
|
|
if (nextSelectionKey.isReadable()) { |
|
|
|
try { |
|
|
|
clearInterestOps(nextSelectionKey, SelectionKey.OP_READ); |
|
|
|
if (nextSelectionKey.isReadable()) { |
|
|
|
Peer peer = getPeerFromChannel((SocketChannel) socketChannel); |
|
|
|
clearInterestOps(nextSelectionKey, SelectionKey.OP_READ); |
|
|
|
if (peer == null) |
|
|
|
Peer peer = getPeerFromChannel((SocketChannel) socketChannel); |
|
|
|
return null; |
|
|
|
if (peer == null) |
|
|
|
|
|
|
|
return null; |
|
|
|
|
|
|
|
|
|
|
|
return new ChannelReadTask((SocketChannel) socketChannel, peer); |
|
|
|
return new ChannelReadTask((SocketChannel) socketChannel, peer); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (nextSelectionKey.isWritable()) { |
|
|
|
if (nextSelectionKey.isWritable()) { |
|
|
|
clearInterestOps(nextSelectionKey, SelectionKey.OP_WRITE); |
|
|
|
clearInterestOps(nextSelectionKey, SelectionKey.OP_WRITE); |
|
|
|
Peer peer = getPeerFromChannel((SocketChannel) socketChannel); |
|
|
|
Peer peer = getPeerFromChannel((SocketChannel) socketChannel); |
|
|
|
if (peer == null) |
|
|
|
if (peer == null) |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
|
|
|
|
|
|
|
|
// Any thread that queues a message to send can set OP_WRITE,
|
|
|
|
// Any thread that queues a message to send can set OP_WRITE,
|
|
|
|
// but we only allow one pending/active ChannelWriteTask per Peer
|
|
|
|
// but we only allow one pending/active ChannelWriteTask per Peer
|
|
|
|
if (!channelsPendingWrite.add(socketChannel)) |
|
|
|
if (!channelsPendingWrite.add(socketChannel)) |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
|
|
|
|
|
|
|
|
return new ChannelWriteTask((SocketChannel) socketChannel, peer); |
|
|
|
return new ChannelWriteTask((SocketChannel) socketChannel, peer); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (nextSelectionKey.isAcceptable()) { |
|
|
|
if (nextSelectionKey.isAcceptable()) { |
|
|
|
clearInterestOps(nextSelectionKey, SelectionKey.OP_ACCEPT); |
|
|
|
clearInterestOps(nextSelectionKey, SelectionKey.OP_ACCEPT); |
|
|
|
return new ChannelAcceptTask((ServerSocketChannel) socketChannel); |
|
|
|
return new ChannelAcceptTask((ServerSocketChannel) socketChannel); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} catch (CancelledKeyException e) { |
|
|
|
|
|
|
|
/* |
|
|
|
|
|
|
|
* Sometimes nextSelectionKey is cancelled / becomes invalid between the isValid() test at line 586 |
|
|
|
|
|
|
|
* and later calls to isReadable() / isWritable() / isAcceptable() which themselves call isValid()! |
|
|
|
|
|
|
|
* Those isXXXable() calls could throw CancelledKeyException, so we catch it here and return null. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|