[#2761] ChannelOutboundBuffer can cause data-corruption because of caching ByteBuffers
Motivation: We cache the ByteBuffers in ChannelOutboundBuffer.nioBuffers() for the Entries in the ChannelOutboundBuffer to reduce some overhead. The problem is this can lead to data-corruption if an incomplete write happens and next time we try to do a non-gathering write. To fix this we should remove the caching which does not help a lot anyway and just make the code buggy. Modifications: Remove the caching of ByteBuffers. Result: No more data-corruption.
This commit is contained in:
parent
ba58f949e8
commit
c7be4e4937
@ -352,31 +352,17 @@ public final class ChannelOutboundBuffer {
|
|||||||
|
|
||||||
if (readableBytes > 0) {
|
if (readableBytes > 0) {
|
||||||
nioBufferSize += readableBytes;
|
nioBufferSize += readableBytes;
|
||||||
int count = entry.count;
|
int count = buf.nioBufferCount();
|
||||||
if (count == -1) {
|
|
||||||
//noinspection ConstantValueVariableUse
|
|
||||||
entry.count = count = buf.nioBufferCount();
|
|
||||||
}
|
|
||||||
int neededSpace = nioBufferCount + count;
|
int neededSpace = nioBufferCount + count;
|
||||||
if (neededSpace > nioBuffers.length) {
|
if (neededSpace > nioBuffers.length) {
|
||||||
nioBuffers = expandNioBufferArray(nioBuffers, neededSpace, nioBufferCount);
|
nioBuffers = expandNioBufferArray(nioBuffers, neededSpace, nioBufferCount);
|
||||||
NIO_BUFFERS.set(threadLocalMap, nioBuffers);
|
NIO_BUFFERS.set(threadLocalMap, nioBuffers);
|
||||||
}
|
}
|
||||||
if (count == 1) {
|
if (count == 1) {
|
||||||
ByteBuffer nioBuf = entry.buf;
|
ByteBuffer nioBuf = buf.internalNioBuffer(readerIndex, readableBytes);
|
||||||
if (nioBuf == null) {
|
|
||||||
// cache ByteBuffer as it may need to create a new ByteBuffer instance if its a
|
|
||||||
// derived buffer
|
|
||||||
entry.buf = nioBuf = buf.internalNioBuffer(readerIndex, readableBytes);
|
|
||||||
}
|
|
||||||
nioBuffers[nioBufferCount ++] = nioBuf;
|
nioBuffers[nioBufferCount ++] = nioBuf;
|
||||||
} else {
|
} else {
|
||||||
ByteBuffer[] nioBufs = entry.bufs;
|
ByteBuffer[] nioBufs = buf.nioBuffers(readerIndex, readableBytes);
|
||||||
if (nioBufs == null) {
|
|
||||||
// cached ByteBuffers as they may be expensive to create in terms
|
|
||||||
// of Object allocation
|
|
||||||
entry.bufs = nioBufs = buf.nioBuffers();
|
|
||||||
}
|
|
||||||
nioBufferCount = fillBufferArray(nioBufs, nioBuffers, nioBufferCount);
|
nioBufferCount = fillBufferArray(nioBufs, nioBuffers, nioBufferCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -586,13 +572,10 @@ public final class ChannelOutboundBuffer {
|
|||||||
private final Handle handle;
|
private final Handle handle;
|
||||||
Entry next;
|
Entry next;
|
||||||
Object msg;
|
Object msg;
|
||||||
ByteBuffer[] bufs;
|
|
||||||
ByteBuffer buf;
|
|
||||||
ChannelPromise promise;
|
ChannelPromise promise;
|
||||||
long progress;
|
long progress;
|
||||||
long total;
|
long total;
|
||||||
int pendingSize;
|
int pendingSize;
|
||||||
int count = -1;
|
|
||||||
boolean cancelled;
|
boolean cancelled;
|
||||||
|
|
||||||
private Entry(Handle handle) {
|
private Entry(Handle handle) {
|
||||||
@ -620,8 +603,6 @@ public final class ChannelOutboundBuffer {
|
|||||||
pendingSize = 0;
|
pendingSize = 0;
|
||||||
total = 0;
|
total = 0;
|
||||||
progress = 0;
|
progress = 0;
|
||||||
bufs = null;
|
|
||||||
buf = null;
|
|
||||||
return pSize;
|
return pSize;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -629,14 +610,11 @@ public final class ChannelOutboundBuffer {
|
|||||||
|
|
||||||
void recycle() {
|
void recycle() {
|
||||||
next = null;
|
next = null;
|
||||||
bufs = null;
|
|
||||||
buf = null;
|
|
||||||
msg = null;
|
msg = null;
|
||||||
promise = null;
|
promise = null;
|
||||||
progress = 0;
|
progress = 0;
|
||||||
total = 0;
|
total = 0;
|
||||||
pendingSize = 0;
|
pendingSize = 0;
|
||||||
count = -1;
|
|
||||||
cancelled = false;
|
cancelled = false;
|
||||||
RECYCLER.recycle(this, handle);
|
RECYCLER.recycle(this, handle);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user