Ensure CombinedChannelDuplexHandler can not be shared.
Motivation: CombinedChannelDuplexHandler must not be shared as it contains state. Modifications: Enforce that it is not shared. Result: Fixes [#6333]
This commit is contained in:
parent
fd2e142e74
commit
78586a99b6
@ -70,7 +70,7 @@ public abstract class ByteToMessageCodec<I> extends ChannelDuplexHandler {
|
|||||||
* {@link ByteBuf}, which is backed by an byte array.
|
* {@link ByteBuf}, which is backed by an byte array.
|
||||||
*/
|
*/
|
||||||
protected ByteToMessageCodec(boolean preferDirect) {
|
protected ByteToMessageCodec(boolean preferDirect) {
|
||||||
CodecUtil.ensureNotSharable(this);
|
ensureNotSharable();
|
||||||
outboundMsgMatcher = TypeParameterMatcher.find(this, ByteToMessageCodec.class, "I");
|
outboundMsgMatcher = TypeParameterMatcher.find(this, ByteToMessageCodec.class, "I");
|
||||||
encoder = new Encoder(preferDirect);
|
encoder = new Encoder(preferDirect);
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ public abstract class ByteToMessageCodec<I> extends ChannelDuplexHandler {
|
|||||||
* {@link ByteBuf}, which is backed by an byte array.
|
* {@link ByteBuf}, which is backed by an byte array.
|
||||||
*/
|
*/
|
||||||
protected ByteToMessageCodec(Class<? extends I> outboundMessageType, boolean preferDirect) {
|
protected ByteToMessageCodec(Class<? extends I> outboundMessageType, boolean preferDirect) {
|
||||||
CodecUtil.ensureNotSharable(this);
|
ensureNotSharable();
|
||||||
outboundMsgMatcher = TypeParameterMatcher.get(outboundMessageType);
|
outboundMsgMatcher = TypeParameterMatcher.get(outboundMessageType);
|
||||||
encoder = new Encoder(preferDirect);
|
encoder = new Encoder(preferDirect);
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ public abstract class ByteToMessageDecoder extends ChannelInboundHandlerAdapter
|
|||||||
private int numReads;
|
private int numReads;
|
||||||
|
|
||||||
protected ByteToMessageDecoder() {
|
protected ByteToMessageDecoder() {
|
||||||
CodecUtil.ensureNotSharable(this);
|
ensureNotSharable();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,32 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2014 The Netty Project
|
|
||||||
*
|
|
||||||
* The Netty Project licenses this file to you under the Apache License,
|
|
||||||
* version 2.0 (the "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at:
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
package io.netty.handler.codec;
|
|
||||||
|
|
||||||
import io.netty.channel.ChannelHandlerAdapter;
|
|
||||||
|
|
||||||
final class CodecUtil {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Throws {@link IllegalStateException} if {@link ChannelHandlerAdapter#isSharable()} returns {@code true}
|
|
||||||
*/
|
|
||||||
static void ensureNotSharable(ChannelHandlerAdapter handler) {
|
|
||||||
if (handler.isSharable()) {
|
|
||||||
throw new IllegalStateException("@Sharable annotation is not allowed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private CodecUtil() { }
|
|
||||||
}
|
|
@ -28,6 +28,15 @@ public abstract class ChannelHandlerAdapter implements ChannelHandler {
|
|||||||
// Not using volatile because it's used only for a sanity check.
|
// Not using volatile because it's used only for a sanity check.
|
||||||
boolean added;
|
boolean added;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Throws {@link IllegalStateException} if {@link ChannelHandlerAdapter#isSharable()} returns {@code true}
|
||||||
|
*/
|
||||||
|
protected void ensureNotSharable() {
|
||||||
|
if (isSharable()) {
|
||||||
|
throw new IllegalStateException("ChannelHandler " + getClass().getName() + " is not allowed to be shared");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return {@code true} if the implementation is {@link Sharable} and so can be added
|
* Return {@code true} if the implementation is {@link Sharable} and so can be added
|
||||||
* to different {@link ChannelPipeline}s.
|
* to different {@link ChannelPipeline}s.
|
||||||
|
@ -45,12 +45,15 @@ public class CombinedChannelDuplexHandler<I extends ChannelInboundHandler, O ext
|
|||||||
* {@link #init(ChannelInboundHandler, ChannelOutboundHandler)} before adding this handler into a
|
* {@link #init(ChannelInboundHandler, ChannelOutboundHandler)} before adding this handler into a
|
||||||
* {@link ChannelPipeline}.
|
* {@link ChannelPipeline}.
|
||||||
*/
|
*/
|
||||||
protected CombinedChannelDuplexHandler() { }
|
protected CombinedChannelDuplexHandler() {
|
||||||
|
ensureNotSharable();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new instance that combines the specified two handlers into one.
|
* Creates a new instance that combines the specified two handlers into one.
|
||||||
*/
|
*/
|
||||||
public CombinedChannelDuplexHandler(I inboundHandler, O outboundHandler) {
|
public CombinedChannelDuplexHandler(I inboundHandler, O outboundHandler) {
|
||||||
|
ensureNotSharable();
|
||||||
init(inboundHandler, outboundHandler);
|
init(inboundHandler, outboundHandler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,4 +387,14 @@ public class CombinedChannelDuplexHandlerTest {
|
|||||||
promise.syncUninterruptibly();
|
promise.syncUninterruptibly();
|
||||||
ch.finish();
|
ch.finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalStateException.class)
|
||||||
|
public void testNotSharable() {
|
||||||
|
new CombinedChannelDuplexHandler<ChannelInboundHandler, ChannelOutboundHandler>() {
|
||||||
|
@Override
|
||||||
|
public boolean isSharable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user