2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.protocol.bgp.rib.impl;
10 import static java.util.Objects.requireNonNull;
12 import io.netty.channel.ChannelFuture;
13 import io.netty.channel.ChannelHandlerContext;
14 import io.netty.channel.ChannelInboundHandlerAdapter;
15 import javax.annotation.concurrent.ThreadSafe;
16 import org.opendaylight.yangtools.yang.binding.Notification;
17 import org.slf4j.Logger;
18 import org.slf4j.LoggerFactory;
21 * A best-effort output limiter. It does not provide any fairness, and acts as a blocking gate-keeper
22 * for a sessions' channel.
25 public final class ChannelOutputLimiter extends ChannelInboundHandlerAdapter {
26 private static final Logger LOG = LoggerFactory.getLogger(ChannelOutputLimiter.class);
27 private final BGPSessionImpl session;
28 private volatile boolean blocked;
30 ChannelOutputLimiter(final BGPSessionImpl session) {
31 this.session = requireNonNull(session);
34 private void ensureWritable() {
36 LOG.trace("Blocked slow path tripped on session {}", this.session);
38 while (this.blocked) {
40 LOG.debug("Waiting for session {} to become writable", this.session);
43 } catch (final InterruptedException e) {
44 throw new IllegalStateException("Interrupted while waiting for channel to come back", e);
48 LOG.debug("Resuming write on session {}", this.session);
53 public void write(final Notification msg) {
55 this.session.write(msg);
58 ChannelFuture writeAndFlush(final Notification msg) {
60 return this.session.writeAndFlush(msg);
68 public void channelWritabilityChanged(final ChannelHandlerContext ctx) throws Exception {
69 final boolean w = ctx.channel().isWritable();
73 LOG.debug("Writes on session {} {}", this.session, w ? "unblocked" : "blocked");
80 super.channelWritabilityChanged(ctx);
84 public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
90 super.channelInactive(ctx);