Retain AbstractBinaryMemcacheDecoder.currentMessage when sending it out and release it when it's not used.
Motivation: AbstractBinaryMemcacheDecoder.currentMessage is not retained after sending it out. Hence, if a message contains `extras`, `io.netty.util.IllegalReferenceCountException` will be thrown in `channelInactive`. Modifications: Retain AbstractBinaryMemcacheDecoder.currentMessage After putting it to `out` and release it when it's not used. Result: No IllegalReferenceCountException or leak.
This commit is contained in:
parent
78b508a7eb
commit
4606890513
@ -79,6 +79,7 @@ public abstract class AbstractBinaryMemcacheDecoder<M extends BinaryMemcacheMess
|
||||
currentMessage = decodeHeader(in);
|
||||
state = State.READ_EXTRAS;
|
||||
} catch (Exception e) {
|
||||
resetDecoder();
|
||||
out.add(invalidMessage(e));
|
||||
return;
|
||||
}
|
||||
@ -94,6 +95,7 @@ public abstract class AbstractBinaryMemcacheDecoder<M extends BinaryMemcacheMess
|
||||
|
||||
state = State.READ_KEY;
|
||||
} catch (Exception e) {
|
||||
resetDecoder();
|
||||
out.add(invalidMessage(e));
|
||||
return;
|
||||
}
|
||||
@ -107,10 +109,10 @@ public abstract class AbstractBinaryMemcacheDecoder<M extends BinaryMemcacheMess
|
||||
currentMessage.setKey(in.toString(in.readerIndex(), keyLength, CharsetUtil.UTF_8));
|
||||
in.skipBytes(keyLength);
|
||||
}
|
||||
|
||||
out.add(currentMessage);
|
||||
out.add(currentMessage.retain());
|
||||
state = State.READ_CONTENT;
|
||||
} catch (Exception e) {
|
||||
resetDecoder();
|
||||
out.add(invalidMessage(e));
|
||||
return;
|
||||
}
|
||||
@ -150,9 +152,11 @@ public abstract class AbstractBinaryMemcacheDecoder<M extends BinaryMemcacheMess
|
||||
out.add(LastMemcacheContent.EMPTY_LAST_CONTENT);
|
||||
}
|
||||
|
||||
resetDecoder();
|
||||
state = State.READ_HEADER;
|
||||
return;
|
||||
} catch (Exception e) {
|
||||
resetDecoder();
|
||||
out.add(invalidChunk(e));
|
||||
return;
|
||||
}
|
||||
@ -200,10 +204,6 @@ public abstract class AbstractBinaryMemcacheDecoder<M extends BinaryMemcacheMess
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
|
||||
super.channelInactive(ctx);
|
||||
|
||||
if (currentMessage != null) {
|
||||
currentMessage.release();
|
||||
}
|
||||
|
||||
resetDecoder();
|
||||
}
|
||||
|
||||
@ -211,7 +211,10 @@ public abstract class AbstractBinaryMemcacheDecoder<M extends BinaryMemcacheMess
|
||||
* Prepare for next decoding iteration.
|
||||
*/
|
||||
protected void resetDecoder() {
|
||||
currentMessage = null;
|
||||
if (currentMessage != null) {
|
||||
currentMessage.release();
|
||||
currentMessage = null;
|
||||
}
|
||||
alreadyReadChunkSize = 0;
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@ import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.MatcherAssert.*;
|
||||
import static org.hamcrest.core.IsNull.notNullValue;
|
||||
import static org.hamcrest.core.IsNull.nullValue;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* Verifies the correct functionality of the {@link AbstractBinaryMemcacheDecoder}.
|
||||
@ -248,4 +249,24 @@ public class BinaryMemcacheDecoderTest {
|
||||
assertThat(content.content().toString(CharsetUtil.UTF_8), is(msgBody));
|
||||
content.release();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRetainCurrentMessageWhenSendingItOut() {
|
||||
channel = new EmbeddedChannel(
|
||||
new BinaryMemcacheRequestEncoder(),
|
||||
new BinaryMemcacheRequestDecoder());
|
||||
|
||||
String key = "Netty";
|
||||
ByteBuf extras = Unpooled.copiedBuffer("extras", CharsetUtil.UTF_8);
|
||||
BinaryMemcacheRequest request = new DefaultBinaryMemcacheRequest(key, extras);
|
||||
request.setKeyLength((short) key.length());
|
||||
request.setExtrasLength((byte) extras.readableBytes());
|
||||
|
||||
assertTrue(channel.writeOutbound(request));
|
||||
assertTrue(channel.writeInbound(channel.outboundMessages().toArray()));
|
||||
|
||||
BinaryMemcacheRequest read = channel.readInbound();
|
||||
read.release();
|
||||
// tearDown will call "channel.finish()"
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user