Use doOnDiscard to free internally queued data buffers
Issue: SPR-17246
This commit is contained in:
@@ -101,8 +101,8 @@ public abstract class DataBufferUtils {
|
||||
bufferSize);
|
||||
return Flux.generate(generator);
|
||||
},
|
||||
DataBufferUtils::closeChannel
|
||||
);
|
||||
DataBufferUtils::closeChannel)
|
||||
.doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,14 +140,16 @@ public abstract class DataBufferUtils {
|
||||
DataBuffer dataBuffer = dataBufferFactory.allocateBuffer(bufferSize);
|
||||
ByteBuffer byteBuffer = dataBuffer.asByteBuffer(0, bufferSize);
|
||||
|
||||
return Flux.using(channelSupplier,
|
||||
Flux<DataBuffer> result = Flux.using(channelSupplier,
|
||||
channel -> Flux.create(sink -> {
|
||||
CompletionHandler<Integer, DataBuffer> completionHandler =
|
||||
new AsynchronousFileChannelReadCompletionHandler(channel,
|
||||
sink, position, dataBufferFactory, bufferSize);
|
||||
channel.read(byteBuffer, position, dataBuffer, completionHandler);
|
||||
}),
|
||||
CompletionHandler<Integer, DataBuffer> completionHandler =
|
||||
new AsynchronousFileChannelReadCompletionHandler(channel,
|
||||
sink, position, dataBufferFactory, bufferSize);
|
||||
channel.read(byteBuffer, position, dataBuffer, completionHandler);
|
||||
}),
|
||||
DataBufferUtils::closeChannel);
|
||||
|
||||
return result.doOnDiscard(PooledDataBuffer.class, DataBufferUtils::release);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -391,12 +393,19 @@ public abstract class DataBufferUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Release the given data buffer, if it is a {@link PooledDataBuffer}.
|
||||
* Release the given data buffer, if it is a {@link PooledDataBuffer} and
|
||||
* has been {@linkplain PooledDataBuffer#isAllocated() allocated}.
|
||||
* @param dataBuffer the data buffer to release
|
||||
* @return {@code true} if the buffer was released; {@code false} otherwise.
|
||||
*/
|
||||
public static boolean release(@Nullable DataBuffer dataBuffer) {
|
||||
return (dataBuffer instanceof PooledDataBuffer && ((PooledDataBuffer) dataBuffer).release());
|
||||
if (dataBuffer instanceof PooledDataBuffer) {
|
||||
PooledDataBuffer pooledDataBuffer = (PooledDataBuffer) dataBuffer;
|
||||
if (pooledDataBuffer.isAllocated()) {
|
||||
return pooledDataBuffer.release();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -259,6 +259,11 @@ public class NettyDataBuffer implements PooledDataBuffer {
|
||||
return new ByteBufOutputStream(this.byteBuf);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllocated() {
|
||||
return this.byteBuf.refCnt() > 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PooledDataBuffer retain() {
|
||||
return new NettyDataBuffer(this.byteBuf.retain(), this.dataBufferFactory);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2016 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -25,6 +25,12 @@ package org.springframework.core.io.buffer;
|
||||
*/
|
||||
public interface PooledDataBuffer extends DataBuffer {
|
||||
|
||||
/**
|
||||
* Return {@code true} if this buffer is allocated; {@code false} if it has been deallocated.
|
||||
* @since 5.1
|
||||
*/
|
||||
boolean isAllocated();
|
||||
|
||||
/**
|
||||
* Increase the reference count for this buffer by one.
|
||||
* @return this buffer
|
||||
@@ -32,9 +38,9 @@ public interface PooledDataBuffer extends DataBuffer {
|
||||
PooledDataBuffer retain();
|
||||
|
||||
/**
|
||||
* Decrease the reference count for this buffer by one, and release it
|
||||
* Decrease the reference count for this buffer by one, and deallocate it
|
||||
* once the count reaches zero.
|
||||
* @return {@code true} if the buffer was released; {@code false} otherwise.
|
||||
* @return {@code true} if the buffer was deallocated; {@code false} otherwise.
|
||||
*/
|
||||
boolean release();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user