George
George

Reputation: 7543

Netty ByteBuf to byte[] decoder

I want to convert incoming Netty's ButeBuf message to a MyBuffer instance of a class of mine. For that I use this MessageToMessageDecoder:

class ByteArrayDecoder extends MessageToMessageDecoder<ByteBuf> {
  @Override
  protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception {
    int length = msg.readableBytes();
    if (msg.hasArray()) {
      out.add(new MyBuffer(msg.array(), msg.arrayOffset(), length));

    } else {
      byte[] bytes = new byte[length];
      msg.getBytes(msg.readerIndex(), bytes);
      out.add(new MyBuffer(bytes, 0, length));
    }
  }
}

Now since the ByteBuf message is reference counted we have to release it after we are done with it. This is done automatically by the MessageToMessageDecoder which we are extending.

Now since the ButeBuf is released doesn't this mean that the backing array is in danger? It would be recycled and I'm not sure what I'm going to see in my MyBuffer's array then.

Is this decoder safe to be used and is this the proper way to write it?

Upvotes: 2

Views: 2182

Answers (1)

Not a JD
Not a JD

Reputation: 1902

Per @Ferrybig suggestion, am making my comment an answer!

ByteBuf.array() returns the actual backing array as you've specified...

Once you've relinquished your handle/reference to it, and the reference count subsequently drops to 0 (either immediately or when everything else gives up its claim), all bets are off.

If you need to maintain what's in the buffer then your MyBuffer will have to take a copy of the array it receives in its constructor.

I've been bitten by this before when an array was repurposed wayyyy after I initially used it. When I came back to it - boom - it had been reused and my data was gone.

So might be worth adding a "copy" flag to the constructor of MyBuffer indicating whether the inbound array needs copying or not.

Upvotes: 4

Related Questions