diff --git a/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java b/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java index 09cf507e90..b3a0a42202 100644 --- a/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java +++ b/transport/src/main/java/io/netty/channel/ChannelOutboundBuffer.java @@ -689,6 +689,36 @@ public final class ChannelOutboundBuffer { return totalPendingSize; } + /** + * Get how many bytes can be written until {@link #isWritable()} returns {@code false}. + * This quantity will always be non-negative. If {@link #isWritable()} is {@code false} then 0. + */ + public long bytesBeforeUnWritable() { + long bytes = channel.config().getWriteBufferHighWaterMark() - totalPendingSize; + // If bytes is negative we know we are not writable, but if bytes is non-negative we have to check writability. + // Note that totalPendingSize and isWritable() use different volatile variables that are not synchronized + // together. totalPendingSize will be updated before isWritable(). + if (bytes > 0) { + return isWritable() ? bytes : 0; + } + return 0; + } + + /** + * Get how many bytes must be drained from the underlying buffer until {@link #isWritable()} returns {@code true}. + * This quantity will always be non-negative. If {@link #isWritable()} is {@code true} then 0. + */ + public long bytesBeforeWritable() { + long bytes = totalPendingSize - channel.config().getWriteBufferLowWaterMark(); + // If bytes is negative we know we are writable, but if bytes is non-negative we have to check writability. + // Note that totalPendingSize and isWritable() use different volatile variables that are not synchronized + // together. totalPendingSize will be updated before isWritable(). + if (bytes > 0) { + return isWritable() ? 0 : bytes; + } + return 0; + } + /** * Call {@link MessageProcessor#processMessage(Object)} for each flushed message * in this {@link ChannelOutboundBuffer} until {@link MessageProcessor#processMessage(Object)}