Repository: netty/netty
Issue: Allow to set a specific ByteBufAllocator for a ChannelHandlerContext
Labels: feature

Sometimes it would be useful to use a different ByteBufAllocator for different ChannelHandlerContext's (and so the handlers which are assigned to them).

Maybe we can make it possible.


Issue comments:
@normanmaurer Maybe it is  already done? It seems can be assigned  by `ChannelConfig`. 

@plucury this is used for all. I may need this per ChannelHandlerContext.

@normanmaurer  Ah, I see. So we need keep a `ByteBufAllocator` instance in `AbstractChannelHandlerContext`, right?

I don't think we need this anymore. Let us close this

@normanmaurer That's OK


Pull request review comments:

Patch that resolved the issue:
diff --git a/transport/src/main/java/io/netty/channel/AbstractChannelHandlerContext.java b/transport/src/main/java/io/netty/channel/AbstractChannelHandlerContext.java
index ad914d05eed..9d5ddd437e0 100644
--- a/transport/src/main/java/io/netty/channel/AbstractChannelHandlerContext.java
+++ b/transport/src/main/java/io/netty/channel/AbstractChannelHandlerContext.java
@@ -210,6 +210,7 @@ private static boolean isSkippable(
     private final DefaultChannelPipeline pipeline;
     private final String name;
     private boolean removed;
+    private volatile ByteBufAllocator allocator;
 
     final int skipFlags;
 
@@ -228,6 +229,12 @@ private static boolean isSkippable(
 
     AbstractChannelHandlerContext(
             DefaultChannelPipeline pipeline, ChannelHandlerInvoker invoker, String name, int skipFlags) {
+        this(pipeline, invoker, name, skipFlags, null);
+    }
+
+    AbstractChannelHandlerContext(
+            DefaultChannelPipeline pipeline, ChannelHandlerInvoker invoker, String name, int skipFlags,
+            ByteBufAllocator allocator) {
 
         if (name == null) {
             throw new NullPointerException("name");
@@ -238,6 +245,7 @@ private static boolean isSkippable(
         this.name = name;
         this.invoker = invoker;
         this.skipFlags = skipFlags;
+        this.allocator = allocator;
     }
 
     /** Invocation initiated by {@link DefaultChannelPipeline#teardownAll()}}. */
@@ -281,7 +289,7 @@ public ChannelPipeline pipeline() {
 
     @Override
     public ByteBufAllocator alloc() {
-        return channel().config().getAllocator();
+        return allocator == null? channel().config().getAllocator() : allocator;
     }
 
     @Override
@@ -585,4 +593,13 @@ ChannelHandlerInvoker unwrapInvoker() {
         }
         return invoker;
     }
+
+    @Override
+    public void setAllocator(ByteBufAllocator allocator) {
+        if (allocator == null) {
+            throw new NullPointerException("allocator");
+        }
+
+        this.allocator = allocator;
+    }
 }
diff --git a/transport/src/main/java/io/netty/channel/ChannelHandlerContext.java b/transport/src/main/java/io/netty/channel/ChannelHandlerContext.java
index 6f204603250..ad98197a032 100644
--- a/transport/src/main/java/io/netty/channel/ChannelHandlerContext.java
+++ b/transport/src/main/java/io/netty/channel/ChannelHandlerContext.java
@@ -497,4 +497,10 @@ public interface ChannelHandlerContext extends AttributeMap {
      */
     ChannelPromise voidPromise();
 
+    /**
+     * Assign {@link ByteBufAllocator}
+     * @param allocator
+     */
+    void setAllocator(ByteBufAllocator allocator);
+
 }


Test patch: