上次说了添加,这次看看移除。
remove(ChannelHandler handler)方法,从pipeline移除指定ChannelHandler对象
@Override
public final ChannelPipeline remove(ChannelHandler handler) {
remove(getContextOrDie(handler));
return this;
}
getContextOrDie(ChannelHandler handler)方法获得相应AbstractChannelHandlerContext节点:
private AbstractChannelHandlerContext getContextOrDie(ChannelHandler handler) {
AbstractChannelHandlerContext ctx = (AbstractChannelHandlerContext) context(handler);
if (ctx == null) {
//若得不到节点,抛异常
throw new NoSuchElementException(handler.getClass().getName());
} else {
return ctx;
}
}
@Override
public final ChannelHandlerContext context(ChannelHandler handler) {
if (handler == null) {
throw new NullPointerException("handler");
}
AbstractChannelHandlerContext ctx = head.next;
// 循环,获得指定 ChannelHandler 对象的节点
for (;;) {
if (ctx == null) {
return null;
}
if (ctx.handler() == handler) {
// ChannelHandler 相等
return ctx;
}
ctx = ctx.next;
}
}
remove(AbstractChannelHandlerContext ctx) 方法,移除指定 AbstractChannelHandlerContext 节点:
private AbstractChannelHandlerContext remove(final AbstractChannelHandlerContext ctx) {
assert ctx != head && ctx != tail;
synchronized (this) {
//防止多线程并发操作 pipeline 底层的双向链表
// 移除节点
remove0(ctx);
// If the registered is false it means that the channel was not registered on an eventloop yet.
// In this case we remove the context from the pipeline and add a task that will call
// ChannelHandler.handlerRemoved(...) once the channel is registered.
if (!registered) {
//Channel未注册
//添加PendingHandlerRemovedTask回调,在Channel注册完成后执行该回调。
callHandlerCallbackLater(ctx, false);
return ctx;
}
EventExecutor executor = ctx.executor();
// 不在 EventLoop 的线程中。
if (!executor.inEventLoop()) {
// 提交 EventLoop 中,
executor.execute(new Runnable() {
@Override
public void run() {
//执行回调 ChannelHandler removed 事件
callHandlerRemoved0(ctx);
}
});
return ctx;
}
}
// 回调 ChannelHandler removed 事件
callHandlerRemoved0(ctx);
return ctx;
}
remove0(AbstractChannelHandlerContext ctx) 方法,从 pipeline 移除指定的 AbstractChannelHandlerContext 节点。
private static void remove0(AbstractChannelHandlerContext ctx) {
// 获得移除节点的前后节点
AbstractChannelHandlerContext prev = ctx.prev;
AbstractChannelHandlerContext next = ctx.next;
// 前后节点互相指向
prev.next = next;
next.prev = prev;
}
callHandlerRemoved0(AbstractChannelHandlerContext) 方法,执行回调 ChannelHandler 移除完成( removed )事件:
private void callHandlerRemoved0(final AbstractChannelHandlerContext ctx) {
// Notify the complete removal.
try {
try {
// 回调 ChannelHandler 移除完成( removed )事件,释放ChannelHandler占用的资源(由于这个方法的执行在EventLoop线程内,所以要尽量避免执行时间过长)
ctx.handler().handlerRemoved(ctx);
} finally {
// 设置 AbstractChannelHandlerContext 已移除
ctx.setRemoved();
}
} catch (Throwable t) {
fireExceptionCaught(new ChannelPipelineException(
ctx.handler().getClass().getName() + ".handlerRemoved() has thrown an exception.", t));
}
}
PendingHandlerRemovedTask 实现 PendingHandlerCallback 抽象类,用于回调移除 ChannelHandler 节点:
private final class PendingHandlerRemovedTask extends PendingHandlerCallback {
PendingHandlerRemovedTask(AbstractChannelHandlerContext ctx) {
super(ctx);
}
@Override
public void run() {
callHandlerRemoved0(ctx);
}
@Override
void execute() {
EventExecutor executor = ctx.executor();
// 在 EventLoop 的线程中,回调 ChannelHandler removed 事件
if (executor.inEventLoop()) {
callHandlerRemoved0(ctx);
} else {
// 提交 EventLoop 中,执行回调 ChannelHandler removed 事件
try {
executor.execute(this);
} catch (RejectedExecutionException e) {
if (logger.isWarnEnabled()) {
logger.warn(
"Can't invoke handlerRemoved() as the EventExecutor {} rejected it," +
" removing handler {}.", executor, ctx.name(), e);
}
// 标记 AbstractChannelHandlerContext 为已移除
// remove0(...) was call before so just call AbstractChannelHandlerContext.setRemoved().
ctx.setRemoved();
}
}
}
}