Skip to content

Commit 6bfe7d0

Browse files
Norman Maurernormanmaurer
authored andcommitted
Disable caching of PooledByteBuf for different threads.
Motivation: We introduced a PoolThreadCache which is used in our PooledByteBufAllocator to reduce the synchronization overhead on PoolArenas when allocate / deallocate PooledByteBuf instances. This cache is used for both the allocation path and deallocation path by: - Look for cached memory in the PoolThreadCache for the Thread that tries to allocate a new PooledByteBuf and if one is found return it. - Add the memory that is used by a PooledByteBuf to the PoolThreadCache of the Thread that release the PooledByteBuf This works out very well when all allocation / deallocation is done in the EventLoop as the EventLoop will be used for read and write. On the otherside this can lead to surprising side-effects if the user allocate from outside the EventLoop and and pass the ByteBuf over for writing. The problem here is that the memory will be added to the PoolThreadCache that did the actual write on the underlying transport and not on the Thread that previously allocated the buffer. Modifications: Don't cache if different Threads are used for allocating/deallocating Result: Less confusing behavior for users that allocate PooledByteBufs from outside the EventLoop.
1 parent 4131e1d commit 6bfe7d0

File tree

2 files changed

+15
-8
lines changed

2 files changed

+15
-8
lines changed

buffer/src/main/java/io/netty/buffer/PoolArena.java

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -187,15 +187,18 @@ private void allocateHuge(PooledByteBuf<T> buf, int reqCapacity) {
187187
buf.initUnpooled(newUnpooledChunk(reqCapacity), reqCapacity);
188188
}
189189

190-
void free(PoolChunk<T> chunk, long handle, int normCapacity) {
190+
void free(PoolChunk<T> chunk, long handle, int normCapacity, boolean sameThreads) {
191191
if (chunk.unpooled) {
192192
destroyChunk(chunk);
193193
} else {
194-
PoolThreadCache cache = parent.threadCache.get();
195-
if (cache.add(this, chunk, handle, normCapacity)) {
196-
// cached so not free it.
197-
return;
194+
if (sameThreads) {
195+
PoolThreadCache cache = parent.threadCache.get();
196+
if (cache.add(this, chunk, handle, normCapacity)) {
197+
// cached so not free it.
198+
return;
199+
}
198200
}
201+
199202
synchronized (this) {
200203
chunk.parent.free(chunk, handle);
201204
}
@@ -295,7 +298,7 @@ void reallocate(PooledByteBuf<T> buf, int newCapacity, boolean freeOldMemory) {
295298
buf.setIndex(readerIndex, writerIndex);
296299

297300
if (freeOldMemory) {
298-
free(oldChunk, oldHandle, oldMaxLength);
301+
free(oldChunk, oldHandle, oldMaxLength, buf.initThread == Thread.currentThread());
299302
}
300303
}
301304

buffer/src/main/java/io/netty/buffer/PooledByteBuf.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ abstract class PooledByteBuf<T> extends AbstractReferenceCountedByteBuf {
3232
protected int offset;
3333
protected int length;
3434
int maxLength;
35-
35+
Thread initThread;
3636
private ByteBuffer tmpNioBuf;
3737

3838
@SuppressWarnings("unchecked")
@@ -53,6 +53,7 @@ void init(PoolChunk<T> chunk, long handle, int offset, int length, int maxLength
5353
this.maxLength = maxLength;
5454
setIndex(0, 0);
5555
tmpNioBuf = null;
56+
initThread = Thread.currentThread();
5657
}
5758

5859
void initUnpooled(PoolChunk<T> chunk, int length) {
@@ -65,6 +66,7 @@ void initUnpooled(PoolChunk<T> chunk, int length) {
6566
this.length = maxLength = length;
6667
setIndex(0, 0);
6768
tmpNioBuf = null;
69+
initThread = Thread.currentThread();
6870
}
6971

7072
@Override
@@ -142,7 +144,9 @@ protected final void deallocate() {
142144
final long handle = this.handle;
143145
this.handle = -1;
144146
memory = null;
145-
chunk.arena.free(chunk, handle, maxLength);
147+
boolean sameThread = initThread == Thread.currentThread();
148+
initThread = null;
149+
chunk.arena.free(chunk, handle, maxLength, sameThread);
146150
recycle();
147151
}
148152
}

0 commit comments

Comments
 (0)