use of java.nio.channels.CancelledKeyException in project quorrabot by GloriousEggroll.
the class WebSocketServer method onWriteDemand.
@Override
public final void onWriteDemand(WebSocket w) {
WebSocketImpl conn = (WebSocketImpl) w;
try {
conn.key.interestOps(SelectionKey.OP_READ | SelectionKey.OP_WRITE);
} catch (CancelledKeyException e) {
// the thread which cancels key is responsible for possible cleanup
conn.outQueue.clear();
}
selector.wakeup();
}
use of java.nio.channels.CancelledKeyException in project quorrabot by GloriousEggroll.
the class WebSocketServer method run.
// Runnable IMPLEMENTATION /////////////////////////////////////////////////
public void run() {
synchronized (this) {
if (selectorthread != null) {
throw new IllegalStateException(getClass().getName() + " can only be started once.");
}
selectorthread = Thread.currentThread();
if (isclosed.get()) {
return;
}
}
selectorthread.setName("WebsocketSelector" + selectorthread.getId());
try {
server = ServerSocketChannel.open();
server.configureBlocking(false);
ServerSocket socket = server.socket();
socket.setReceiveBufferSize(WebSocketImpl.RCVBUF);
socket.bind(address);
selector = Selector.open();
server.register(selector, server.validOps());
} catch (IOException ex) {
handleFatal(null, ex);
return;
}
try {
while (!selectorthread.isInterrupted()) {
SelectionKey key = null;
WebSocketImpl conn = null;
try {
selector.select();
Set<SelectionKey> keys = selector.selectedKeys();
Iterator<SelectionKey> i = keys.iterator();
while (i.hasNext()) {
key = i.next();
if (!key.isValid()) {
// Object o = key.attachment();
continue;
}
if (key.isAcceptable()) {
if (!onConnect(key)) {
key.cancel();
continue;
}
SocketChannel channel = server.accept();
channel.configureBlocking(false);
WebSocketImpl w = wsf.createWebSocket(this, drafts, channel.socket());
w.key = channel.register(selector, SelectionKey.OP_READ, w);
w.channel = wsf.wrapChannel(channel, w.key);
i.remove();
allocateBuffers(w);
continue;
}
if (key.isReadable()) {
conn = (WebSocketImpl) key.attachment();
ByteBuffer buf = takeBuffer();
try {
if (SocketChannelIOHelper.read(buf, conn, conn.channel)) {
if (buf.hasRemaining()) {
conn.inQueue.put(buf);
queue(conn);
i.remove();
if (conn.channel instanceof WrappedByteChannel) {
if (((WrappedByteChannel) conn.channel).isNeedRead()) {
iqueue.add(conn);
}
}
} else {
pushBuffer(buf);
}
} else {
pushBuffer(buf);
}
} catch (IOException e) {
pushBuffer(buf);
throw e;
}
}
if (key.isWritable()) {
conn = (WebSocketImpl) key.attachment();
if (SocketChannelIOHelper.batch(conn, conn.channel)) {
if (key.isValid()) {
key.interestOps(SelectionKey.OP_READ);
}
}
}
}
while (!iqueue.isEmpty()) {
conn = iqueue.remove(0);
WrappedByteChannel c = ((WrappedByteChannel) conn.channel);
ByteBuffer buf = takeBuffer();
try {
if (SocketChannelIOHelper.readMore(buf, conn, c)) {
iqueue.add(conn);
}
if (buf.hasRemaining()) {
conn.inQueue.put(buf);
queue(conn);
} else {
pushBuffer(buf);
}
} catch (IOException e) {
pushBuffer(buf);
throw e;
}
}
} catch (CancelledKeyException e) {
// an other thread may cancel the key
} catch (ClosedByInterruptException e) {
// do the same stuff as when InterruptedException is thrown
return;
} catch (IOException ex) {
if (key != null) {
key.cancel();
}
handleIOException(key, conn, ex);
} catch (InterruptedException e) {
// FIXME controlled shutdown (e.g. take care of buffermanagement)
return;
}
}
} catch (RuntimeException e) {
// should hopefully never occur
handleFatal(null, e);
} finally {
if (decoders != null) {
for (WebSocketWorker w : decoders) {
w.interrupt();
}
}
if (server != null) {
try {
server.close();
} catch (IOException e) {
onError(null, e);
}
}
}
}
use of java.nio.channels.CancelledKeyException in project elasticsearch by elastic.
the class TcpTransport method onException.
protected void onException(Channel channel, Exception e) throws IOException {
if (!lifecycle.started()) {
// just close and ignore - we are already stopped and just need to make sure we release all resources
disconnectFromNodeChannel(channel, e);
return;
}
if (isCloseConnectionException(e)) {
logger.trace((Supplier<?>) () -> new ParameterizedMessage("close connection exception caught on transport layer [{}], disconnecting from relevant node", channel), e);
// close the channel, which will cause a node to be disconnected if relevant
disconnectFromNodeChannel(channel, e);
} else if (isConnectException(e)) {
logger.trace((Supplier<?>) () -> new ParameterizedMessage("connect exception caught on transport layer [{}]", channel), e);
// close the channel as safe measure, which will cause a node to be disconnected if relevant
disconnectFromNodeChannel(channel, e);
} else if (e instanceof BindException) {
logger.trace((Supplier<?>) () -> new ParameterizedMessage("bind exception caught on transport layer [{}]", channel), e);
// close the channel as safe measure, which will cause a node to be disconnected if relevant
disconnectFromNodeChannel(channel, e);
} else if (e instanceof CancelledKeyException) {
logger.trace((Supplier<?>) () -> new ParameterizedMessage("cancelled key exception caught on transport layer [{}], disconnecting from relevant node", channel), e);
// close the channel as safe measure, which will cause a node to be disconnected if relevant
disconnectFromNodeChannel(channel, e);
} else if (e instanceof TcpTransport.HttpOnTransportException) {
// in case we are able to return data, serialize the exception content and sent it back to the client
if (isOpen(channel)) {
final Runnable closeChannel = () -> {
try {
closeChannels(Collections.singletonList(channel));
} catch (IOException e1) {
logger.debug("failed to close httpOnTransport channel", e1);
}
};
boolean success = false;
try {
sendMessage(channel, new BytesArray(e.getMessage().getBytes(StandardCharsets.UTF_8)), closeChannel);
success = true;
} finally {
if (success == false) {
// it's fine to call this more than once
closeChannel.run();
}
}
}
} else {
logger.warn((Supplier<?>) () -> new ParameterizedMessage("exception caught on transport layer [{}], closing connection", channel), e);
// close the channel, which will cause a node to be disconnected if relevant
disconnectFromNodeChannel(channel, e);
}
}
use of java.nio.channels.CancelledKeyException in project j2objc by google.
the class AbstractSelectableChannel method register.
/**
* Registers this channel with the specified selector for the specified
* interest set. If the channel is already registered with the selector, the
* {@link SelectionKey interest set} is updated to {@code interestSet} and
* the corresponding selection key is returned. If the channel is not yet
* registered, this method calls the {@code register} method of
* {@code selector} and adds the selection key to this channel's key set.
*
* @param selector
* the selector with which to register this channel.
* @param interestSet
* this channel's {@link SelectionKey interest set}.
* @param attachment
* the object to attach, can be {@code null}.
* @return the selection key for this registration.
* @throws CancelledKeyException
* if this channel is registered but its key has been canceled.
* @throws ClosedChannelException
* if this channel is closed.
* @throws IllegalArgumentException
* if {@code interestSet} is not supported by this channel.
* @throws IllegalBlockingModeException
* if this channel is in blocking mode.
* @throws IllegalSelectorException
* if this channel does not have the same provider as the given
* selector.
*/
@Override
public final SelectionKey register(Selector selector, int interestSet, Object attachment) throws ClosedChannelException {
if (!isOpen()) {
throw new ClosedChannelException();
}
if (!((interestSet & ~validOps()) == 0)) {
throw new IllegalArgumentException("no valid ops in interest set: " + interestSet);
}
synchronized (blockingLock) {
if (isBlocking) {
throw new IllegalBlockingModeException();
}
if (!selector.isOpen()) {
if (interestSet == 0) {
// throw ISE exactly to keep consistency
throw new IllegalSelectorException();
}
// throw NPE exactly to keep consistency
throw new NullPointerException("selector not open");
}
SelectionKey key = keyFor(selector);
if (key == null) {
key = ((AbstractSelector) selector).register(this, interestSet, attachment);
keyList.add(key);
} else {
if (!key.isValid()) {
throw new CancelledKeyException();
}
key.interestOps(interestSet);
key.attach(attachment);
}
return key;
}
}
use of java.nio.channels.CancelledKeyException in project AndroidAsync by koush.
the class AsyncServer method runLoop.
private static void runLoop(final AsyncServer server, final SelectorWrapper selector, final PriorityQueue<Scheduled> queue) throws AsyncSelectorException {
// Log.i(LOGTAG, "Keys: " + selector.keys().size());
boolean needsSelect = true;
// run the queue to populate the selector with keys
long wait = lockAndRunQueue(server, queue);
try {
synchronized (server) {
// select now to see if anything is ready immediately. this
// also clears the canceled key queue.
int readyNow = selector.selectNow();
if (readyNow == 0) {
// which means it would be time to turn this thread off.
if (selector.keys().size() == 0 && wait == QUEUE_EMPTY) {
// Log.i(LOGTAG, "Shutting down. keys: " + selector.keys().size() + " keepRunning: " + keepRunning);
return;
}
} else {
needsSelect = false;
}
}
if (needsSelect) {
if (wait == QUEUE_EMPTY) {
// wait until woken up
selector.select();
} else {
// nothing to select immediately but there's something pending so let's block that duration and wait.
selector.select(wait);
}
}
} catch (Exception e) {
throw new AsyncSelectorException(e);
}
// process whatever keys are ready
Set<SelectionKey> readyKeys = selector.selectedKeys();
for (SelectionKey key : readyKeys) {
try {
if (key.isAcceptable()) {
ServerSocketChannel nextReady = (ServerSocketChannel) key.channel();
SocketChannel sc = null;
SelectionKey ckey = null;
try {
sc = nextReady.accept();
if (sc == null)
continue;
sc.configureBlocking(false);
ckey = sc.register(selector.getSelector(), SelectionKey.OP_READ);
ListenCallback serverHandler = (ListenCallback) key.attachment();
AsyncNetworkSocket handler = new AsyncNetworkSocket();
handler.attach(sc, (InetSocketAddress) sc.socket().getRemoteSocketAddress());
handler.setup(server, ckey);
ckey.attach(handler);
serverHandler.onAccepted(handler);
} catch (IOException e) {
StreamUtility.closeQuietly(sc);
if (ckey != null)
ckey.cancel();
}
} else if (key.isReadable()) {
AsyncNetworkSocket handler = (AsyncNetworkSocket) key.attachment();
int transmitted = handler.onReadable();
server.onDataReceived(transmitted);
} else if (key.isWritable()) {
AsyncNetworkSocket handler = (AsyncNetworkSocket) key.attachment();
handler.onDataWritable();
} else if (key.isConnectable()) {
ConnectFuture cancel = (ConnectFuture) key.attachment();
SocketChannel sc = (SocketChannel) key.channel();
key.interestOps(SelectionKey.OP_READ);
AsyncNetworkSocket newHandler;
try {
sc.finishConnect();
newHandler = new AsyncNetworkSocket();
newHandler.setup(server, key);
newHandler.attach(sc, (InetSocketAddress) sc.socket().getRemoteSocketAddress());
key.attach(newHandler);
} catch (IOException ex) {
key.cancel();
StreamUtility.closeQuietly(sc);
if (cancel.setComplete(ex))
cancel.callback.onConnectCompleted(ex, null);
continue;
}
try {
if (cancel.setComplete(newHandler))
cancel.callback.onConnectCompleted(null, newHandler);
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
Log.i(LOGTAG, "wtf");
throw new RuntimeException("Unknown key state.");
}
} catch (CancelledKeyException ex) {
}
}
readyKeys.clear();
}
Aggregations