Bug 6585: BGP ChannelOutputLimiter waits forever 90/45390/2
authorMilos Fabian <milfabia@cisco.com>
Wed, 31 Aug 2016 15:40:49 +0000 (17:40 +0200)
committerMilos Fabian <milfabia@cisco.com>
Wed, 14 Sep 2016 09:32:18 +0000 (09:32 +0000)
After a while (when an output buffer reach upper bound),
BGP's ChannelOutputLimiter handler get stacked waiting for the channel to become writable again.
The writability change never happen, however socket flush is invoked,
so the session peer dies on holdtimer expiration.

Looks like calling #flush when writability changes to non-writable has no effect.
Invoking #flush in #ensureWritable makes the expected action.

Change-Id: I95681d87c30aff82ec360a2d13fc01fe35873507
Signed-off-by: Milos Fabian <milfabia@cisco.com>
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ChannelOutputLimiter.java

index 21150b9431bc9b6fddeb25ac645425edae7deec7..880542c190583d0d45dfc42ff6b466f5567d85a4 100644 (file)
@@ -36,6 +36,7 @@ final class ChannelOutputLimiter extends ChannelInboundHandlerAdapter {
                 while (blocked) {
                     try {
                         LOG.debug("Waiting for session {} to become writable", session);
+                        flush();
                         this.wait();
                     } catch (InterruptedException e) {
                         throw new IllegalStateException("Interrupted while waiting for channel to come back", e);
@@ -70,9 +71,7 @@ final class ChannelOutputLimiter extends ChannelInboundHandlerAdapter {
             LOG.debug("Writes on session {} {}", session, w ? "unblocked" : "blocked");
 
             if (w) {
-                this.notifyAll();
-            } else {
-                flush();
+                notifyAll();
             }
         }
 
@@ -83,7 +82,7 @@ final class ChannelOutputLimiter extends ChannelInboundHandlerAdapter {
     public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
         synchronized (this) {
             blocked = false;
-            this.notifyAll();
+            notifyAll();
         }
 
         super.channelInactive(ctx);