Browse Source

Fix refCount issue in LeakAwareDataBuffer

LeakAwareDataBuffer was keeping its own refCount rather than checking
through the delegate. This leads to false leak reports in a sequence
where an allocated buffer is retained and then sliced since it is not
aware of the changes to the refCount through the slice.
pull/23050/head
Rossen Stoyanchev 6 years ago
parent
commit
3ebbfa2191
  1. 15
      spring-core/src/test/java/org/springframework/core/io/buffer/LeakAwareDataBuffer.java
  2. 6
      spring-core/src/test/java/org/springframework/core/io/buffer/LeakAwareDataBufferFactory.java

15
spring-core/src/test/java/org/springframework/core/io/buffer/LeakAwareDataBuffer.java

@ -37,8 +37,6 @@ class LeakAwareDataBuffer implements PooledDataBuffer { @@ -37,8 +37,6 @@ class LeakAwareDataBuffer implements PooledDataBuffer {
private final LeakAwareDataBufferFactory dataBufferFactory;
private int refCount = 1;
LeakAwareDataBuffer(DataBuffer delegate, LeakAwareDataBufferFactory dataBufferFactory) {
Assert.notNull(delegate, "Delegate must not be null");
@ -67,19 +65,24 @@ class LeakAwareDataBuffer implements PooledDataBuffer { @@ -67,19 +65,24 @@ class LeakAwareDataBuffer implements PooledDataBuffer {
@Override
public boolean isAllocated() {
return this.refCount > 0;
return this.delegate instanceof PooledDataBuffer &&
((PooledDataBuffer) this.delegate).isAllocated();
}
@Override
public PooledDataBuffer retain() {
this.refCount++;
if (this.delegate instanceof PooledDataBuffer) {
((PooledDataBuffer) this.delegate).retain();
}
return this;
}
@Override
public boolean release() {
this.refCount--;
return this.refCount == 0;
if (this.delegate instanceof PooledDataBuffer) {
((PooledDataBuffer) this.delegate).release();
}
return isAllocated();
}
// delegation

6
spring-core/src/test/java/org/springframework/core/io/buffer/LeakAwareDataBufferFactory.java

@ -99,16 +99,16 @@ public class LeakAwareDataBufferFactory implements DataBufferFactory { @@ -99,16 +99,16 @@ public class LeakAwareDataBufferFactory implements DataBufferFactory {
@Override
public DataBuffer allocateBuffer() {
return allocateBufferInternal(this.delegate.allocateBuffer());
return createLeakAwareDataBuffer(this.delegate.allocateBuffer());
}
@Override
public DataBuffer allocateBuffer(int initialCapacity) {
return allocateBufferInternal(this.delegate.allocateBuffer(initialCapacity));
return createLeakAwareDataBuffer(this.delegate.allocateBuffer(initialCapacity));
}
@NotNull
private DataBuffer allocateBufferInternal(DataBuffer delegateBuffer) {
private DataBuffer createLeakAwareDataBuffer(DataBuffer delegateBuffer) {
LeakAwareDataBuffer dataBuffer = new LeakAwareDataBuffer(delegateBuffer, this);
this.created.add(dataBuffer);
return dataBuffer;

Loading…
Cancel
Save