/** * See {@link ThreadPoolExecutor#shutdownNow()} for how it handles the shutdown. If <code>true * </code> is given to this method it also notifies all {@link ChannelFuture}'s of the not * executed {@link ChannelEventRunnable}'s. * * <p>Be aware that if you call this with <code>false</code> you will need to handle the * notification of the {@link ChannelFuture}'s by your self. So only use this if you really have a * use-case for it. */ public List<Runnable> shutdownNow(boolean notify) { if (!notify) { return super.shutdownNow(); } Throwable cause = null; Set<Channel> channels = null; List<Runnable> tasks = super.shutdownNow(); // loop over all tasks and cancel the ChannelFuture of the ChannelEventRunable's for (Runnable task : tasks) { if (task instanceof ChannelEventRunnable) { if (cause == null) { cause = new IOException("Unable to process queued event"); } ChannelEvent event = ((ChannelEventRunnable) task).getEvent(); event.getFuture().setFailure(cause); if (channels == null) { channels = new HashSet<Channel>(); } // store the Channel of the event for later notification of the exceptionCaught event channels.add(event.getChannel()); } } // loop over all channels and fire an exceptionCaught event if (channels != null) { for (Channel channel : channels) { Channels.fireExceptionCaughtLater(channel, cause); } } return tasks; }
void disconnect(NioDatagramChannel channel, ChannelFuture future) { boolean connected = channel.isConnected(); boolean iothread = isIoThread(); try { channel.getJdkChannel().disconnectSocket(); future.setSuccess(); if (connected) { if (iothread) { fireChannelDisconnected(channel); } else { fireChannelDisconnectedLater(channel); } } } catch (Throwable t) { future.setFailure(t); if (iothread) { fireExceptionCaught(channel, t); } else { fireExceptionCaughtLater(channel, t); } } }