Netty의 ChannelPipeline(2) ChannelHandler 제거
20101 단어 Netty
@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 추상 클래스를 실현하고 채널Handler 노드를 리셋하는 데 사용됩니다.
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();
}
}
}
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
[ 네티 인 액션 ] 7. EventLoop와 스레딩 모델또한 애플리케이션의 동시성 요건이나 전반적인 복잡성 때문에 프로젝트의 수명주기 동안 다른 스레드 관련 문제가 발생할 수 있다. 1. io.netty.util.concurrent 패키지는 JDK 패키지인 java.ut...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.