Fixed occasional on the selector - it shouldn't crash the application

This commit is contained in:
Christian Basler 2017-07-22 08:01:59 +02:00
parent 6c04aa683e
commit d9e52c85c3

View File

@ -203,73 +203,77 @@ class NioNetworkHandler : NetworkHandler, InternalContext.ContextHolder {
serverChannel.register(selector, OP_ACCEPT, null) serverChannel.register(selector, OP_ACCEPT, null)
while (selector.isOpen) { while (selector.isOpen) {
selector.select(1000) try {
val keyIterator = selector.selectedKeys().iterator() selector.select(1000)
while (keyIterator.hasNext()) { val keyIterator = selector.selectedKeys().iterator()
val key = keyIterator.next() while (keyIterator.hasNext()) {
keyIterator.remove() val key = keyIterator.next()
if (key.attachment() == null) { keyIterator.remove()
try { if (key.attachment() == null) {
if (key.isAcceptable) { try {
// handle accept if (key.isAcceptable) {
try { // handle accept
val accepted = (key.channel() as ServerSocketChannel).accept() try {
accepted.configureBlocking(false) val accepted = (key.channel() as ServerSocketChannel).accept()
val connection = Connection(ctx, SERVER, accepted.configureBlocking(false)
NetworkAddress( val connection = Connection(ctx, SERVER,
time = now, NetworkAddress(
stream = 1L, time = now,
socket = accepted.socket()!! stream = 1L,
), socket = accepted.socket()!!
requestedObjects, 0 ),
) requestedObjects, 0
connections.put( )
connection, connections.put(
accepted.register(selector, OP_READ or OP_WRITE, connection) connection,
) accepted.register(selector, OP_READ or OP_WRITE, connection)
} catch (e: AsynchronousCloseException) { )
LOG.trace(e.message) } catch (e: AsynchronousCloseException) {
} catch (e: IOException) { LOG.trace(e.message)
LOG.error(e.message, e) } catch (e: IOException) {
} LOG.error(e.message, e)
}
}
} catch (e: CancelledKeyException) {
LOG.debug(e.message, e)
}
} else {
// handle read/write
val channel = key.channel() as SocketChannel
val connection = key.attachment() as Connection
try {
if (key.isConnectable) {
if (!channel.finishConnect()) {
continue
} }
} catch (e: CancelledKeyException) {
LOG.debug(e.message, e)
} }
if (key.isWritable) {
write(channel, connection.io) } else {
// handle read/write
val channel = key.channel() as SocketChannel
val connection = key.attachment() as Connection
try {
if (key.isConnectable) {
if (!channel.finishConnect()) {
continue
}
}
if (key.isWritable) {
write(channel, connection.io)
}
if (key.isReadable) {
read(channel, connection.io)
}
if (connection.state == Connection.State.DISCONNECTED) {
key.interestOps(0)
channel.close()
} else if (connection.io.isWritePending) {
key.interestOps(OP_READ or OP_WRITE)
} else {
key.interestOps(OP_READ)
}
} catch (e: CancelledKeyException) {
connection.disconnect()
} catch (e: NodeException) {
connection.disconnect()
} catch (e: IOException) {
connection.disconnect()
} }
if (key.isReadable) {
read(channel, connection.io)
}
if (connection.state == Connection.State.DISCONNECTED) {
key.interestOps(0)
channel.close()
} else if (connection.io.isWritePending) {
key.interestOps(OP_READ or OP_WRITE)
} else {
key.interestOps(OP_READ)
}
} catch (e: CancelledKeyException) {
connection.disconnect()
} catch (e: NodeException) {
connection.disconnect()
} catch (e: IOException) {
connection.disconnect()
} }
} }
} catch (e: CancelledKeyException) {
LOG.debug(e.message, e)
} }
// set interest ops // set interest ops
for ((connection, selectionKey) in connections) { for ((connection, selectionKey) in connections) {