From 3767f6fd3430a631a2740aba17dfd9e38a2c54f7 Mon Sep 17 00:00:00 2001 From: Lari Hotari Date: Wed, 22 May 2024 20:53:20 +0300 Subject: [PATCH] Revisit the approach once again: retainedDuplicate() is needed --- .../apache/pulsar/common/protocol/ByteBufPair.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/ByteBufPair.java b/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/ByteBufPair.java index 68e4cc07ac4c0..c283f9ed5eb22 100644 --- a/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/ByteBufPair.java +++ b/pulsar-common/src/main/java/org/apache/pulsar/common/protocol/ByteBufPair.java @@ -122,10 +122,9 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) // Write each buffer individually on the socket. The retain() here is needed to preserve the fact that // ByteBuf are automatically released after a write. If the ByteBufPair ref count is increased and it // gets written multiple times, the individual buffers refcount should be reflected as well. - // .asReadOnly() is needed to prevent SslHandler from modifying the input buffers. try { - ctx.write(b.getFirst().asReadOnly().retain(), ctx.voidPromise()); - ctx.write(b.getSecond().asReadOnly().retain(), promise); + ctx.write(readOnlyRetainedDuplicate(b.getFirst()), ctx.voidPromise()); + ctx.write(readOnlyRetainedDuplicate(b.getSecond()), promise); } finally { ReferenceCountUtil.safeRelease(b); } @@ -133,5 +132,13 @@ public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) ctx.write(msg, promise); } } + + // .asReadOnly() is needed to prevent SslHandler from modifying the input buffers. + private static ByteBuf readOnlyRetainedDuplicate(ByteBuf buf) { + // If the buffer is already read-only, .asReadOnly() will return the same buffer. + // That's why the additional .retainedDuplicate() is needed to ensure that the returned buffer + // has independent readIndex and writeIndex. + return buf.asReadOnly().retainedDuplicate(); + } } }