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 com.google.common.base.Preconditions;
11 import io.netty.channel.ChannelFuture;
12 import io.netty.channel.ChannelHandlerContext;
13 import io.netty.channel.ChannelInboundHandlerAdapter;
14 import javax.annotation.concurrent.ThreadSafe;
15 import org.opendaylight.yangtools.yang.binding.Notification;
16 import org.slf4j.Logger;
17 import org.slf4j.LoggerFactory;
20 * A best-effort output limiter. It does not provide any fairness, and acts as a blocking gate-keeper
21 * for a sessions' channel.
24 public final class ChannelOutputLimiter extends ChannelInboundHandlerAdapter {
25 private static final Logger LOG = LoggerFactory.getLogger(ChannelOutputLimiter.class);
26 private final BGPSessionImpl session;
27 private volatile boolean blocked;
29 ChannelOutputLimiter(final BGPSessionImpl session) {
30 this.session = Preconditions.checkNotNull(session);
33 private void ensureWritable() {
35 LOG.trace("Blocked slow path tripped on session {}", this.session);
37 while (this.blocked) {
39 LOG.debug("Waiting for session {} to become writable", this.session);
42 } catch (final InterruptedException e) {
43 throw new IllegalStateException("Interrupted while waiting for channel to come back", e);
47 LOG.debug("Resuming write on session {}", this.session);
52 public void write(final Notification msg) {
54 this.session.write(msg);
57 ChannelFuture writeAndFlush(final Notification msg) {
59 return this.session.writeAndFlush(msg);
67 public void channelWritabilityChanged(final ChannelHandlerContext ctx) throws Exception {
68 final boolean w = ctx.channel().isWritable();
72 LOG.debug("Writes on session {} {}", this.session, w ? "unblocked" : "blocked");
79 super.channelWritabilityChanged(ctx);
83 public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
89 super.channelInactive(ctx);