View Javadoc

    1   /*
    2    * Copyright 2009 Red Hat, Inc.
    3    *
    4    * Red Hat licenses this file to you under the Apache License, version 2.0
    5    * (the "License"); you may not use this file except in compliance with the
    6    * License.  You may obtain a copy of the License at:
    7    *
    8    *    http://www.apache.org/licenses/LICENSE-2.0
    9    *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
    13   * License for the specific language governing permissions and limitations
    14   * under the License.
    15   */
    16  package org.jboss.netty.channel.socket.nio;
    17
    18  import java.net.Socket;
    19  import java.util.Map;
    20
    21  import org.jboss.netty.channel.AdaptiveReceiveBufferSizePredictorFactory;
    22  import org.jboss.netty.channel.ChannelException;
    23  import org.jboss.netty.channel.ReceiveBufferSizePredictor;
    24  import org.jboss.netty.channel.ReceiveBufferSizePredictorFactory;
    25  import org.jboss.netty.channel.socket.DefaultSocketChannelConfig;
    26  import org.jboss.netty.logging.InternalLogger;
    27  import org.jboss.netty.logging.InternalLoggerFactory;
    28  import org.jboss.netty.util.internal.ConversionUtil;
    29
    30  /**
    31   * The default {@link NioSocketChannelConfig} implementation.
    32   *
    33   * @author <a href="http://www.jboss.org/netty/">The Netty Project</a>
    34   * @author <a href="http://gleamynode.net/">Trustin Lee</a>
    35   *
    36   * @version $Rev: 2087 $, $Date: 2010-01-27 00:41:16 +0900 (Wed, 27 Jan 2010) $
    37   *
    38   */
    39  class DefaultNioSocketChannelConfig extends DefaultSocketChannelConfig
    40          implements NioSocketChannelConfig {
    41
    42      private static final InternalLogger logger =
    43          InternalLoggerFactory.getInstance(DefaultNioSocketChannelConfig.class);
    44
    45      private static final ReceiveBufferSizePredictorFactory DEFAULT_PREDICTOR_FACTORY =
    46          new AdaptiveReceiveBufferSizePredictorFactory();
    47
    48      private volatile int writeBufferHighWaterMark = 64 * 1024;
    49      private volatile int writeBufferLowWaterMark  = 32 * 1024;
    50      private volatile ReceiveBufferSizePredictor predictor;
    51      private volatile ReceiveBufferSizePredictorFactory predictorFactory = DEFAULT_PREDICTOR_FACTORY;
    52      private volatile int writeSpinCount = 16;
    53
    54      DefaultNioSocketChannelConfig(Socket socket) {
    55          super(socket);
    56      }
    57
    58      @Override
    59      public void setOptions(Map<String, Object> options) {
    60          super.setOptions(options);
    61          if (getWriteBufferHighWaterMark() < getWriteBufferLowWaterMark()) {
    62              // Recover the integrity of the configuration with a sensible value.
    63              setWriteBufferLowWaterMark0(getWriteBufferHighWaterMark() >>> 1);
    64              // Notify the user about misconfiguration.
    65              logger.warn(
    66                      "writeBufferLowWaterMark cannot be greater than " +
    67                      "writeBufferHighWaterMark; setting to the half of the " +
    68                      "writeBufferHighWaterMark.");
    69          }
    70      }
    71
    72      @Override
    73      public boolean setOption(String key, Object value) {
    74          if (super.setOption(key, value)) {
    75              return true;
    76          }
    77
    78          if (key.equals("writeBufferHighWaterMark")) {
    79              setWriteBufferHighWaterMark0(ConversionUtil.toInt(value));
    80          } else if (key.equals("writeBufferLowWaterMark")) {
    81              setWriteBufferLowWaterMark0(ConversionUtil.toInt(value));
    82          } else if (key.equals("writeSpinCount")) {
    83              setWriteSpinCount(ConversionUtil.toInt(value));
    84          } else if (key.equals("receiveBufferSizePredictorFactory")) {
    85              setReceiveBufferSizePredictorFactory((ReceiveBufferSizePredictorFactory) value);
    86          } else if (key.equals("receiveBufferSizePredictor")) {
    87              setReceiveBufferSizePredictor((ReceiveBufferSizePredictor) value);
    88          } else {
    89              return false;
    90          }
    91          return true;
    92      }
    93
    94      public int getWriteBufferHighWaterMark() {
    95          return writeBufferHighWaterMark;
    96      }
    97
    98      public void setWriteBufferHighWaterMark(int writeBufferHighWaterMark) {
    99          if (writeBufferHighWaterMark < getWriteBufferLowWaterMark()) {
    100             throw new IllegalArgumentException(
    101                     "writeBufferHighWaterMark cannot be less than " +
    102                     "writeBufferLowWaterMark (" + getWriteBufferLowWaterMark() + "): " +
    103                     writeBufferHighWaterMark);
    104         }
    105         setWriteBufferHighWaterMark0(writeBufferHighWaterMark);
    106     }
    107
    108     private void setWriteBufferHighWaterMark0(int writeBufferHighWaterMark) {
    109         if (writeBufferHighWaterMark < 0) {
    110             throw new IllegalArgumentException(
    111                     "writeBufferHighWaterMark: " + writeBufferHighWaterMark);
    112         }
    113         this.writeBufferHighWaterMark = writeBufferHighWaterMark;
    114     }
    115
    116     public int getWriteBufferLowWaterMark() {
    117         return writeBufferLowWaterMark;
    118     }
    119
    120     public void setWriteBufferLowWaterMark(int writeBufferLowWaterMark) {
    121         if (writeBufferLowWaterMark > getWriteBufferHighWaterMark()) {
    122             throw new IllegalArgumentException(
    123                     "writeBufferLowWaterMark cannot be greater than " +
    124                     "writeBufferHighWaterMark (" + getWriteBufferHighWaterMark() + "): " +
    125                     writeBufferLowWaterMark);
    126         }
    127         setWriteBufferLowWaterMark0(writeBufferLowWaterMark);
    128     }
    129
    130     private void setWriteBufferLowWaterMark0(int writeBufferLowWaterMark) {
    131         if (writeBufferLowWaterMark < 0) {
    132             throw new IllegalArgumentException(
    133                     "writeBufferLowWaterMark: " + writeBufferLowWaterMark);
    134         }
    135         this.writeBufferLowWaterMark = writeBufferLowWaterMark;
    136     }
    137
    138     public int getWriteSpinCount() {
    139         return writeSpinCount;
    140     }
    141
    142     public void setWriteSpinCount(int writeSpinCount) {
    143         if (writeSpinCount <= 0) {
    144             throw new IllegalArgumentException(
    145                     "writeSpinCount must be a positive integer.");
    146         }
    147         this.writeSpinCount = writeSpinCount;
    148     }
    149
    150     public ReceiveBufferSizePredictor getReceiveBufferSizePredictor() {
    151         ReceiveBufferSizePredictor predictor = this.predictor;
    152         if (predictor == null) {
    153             try {
    154                 this.predictor = predictor = getReceiveBufferSizePredictorFactory().getPredictor();
    155             } catch (Exception e) {
    156                 throw new ChannelException(
    157                         "Failed to create a new " +
    158                         ReceiveBufferSizePredictor.class.getSimpleName() + '.',
    159                         e);
    160             }
    161         }
    162         return predictor;
    163     }
    164
    165     public void setReceiveBufferSizePredictor(
    166             ReceiveBufferSizePredictor predictor) {
    167         if (predictor == null) {
    168             throw new NullPointerException("predictor");
    169         }
    170         this.predictor = predictor;
    171     }
    172
    173     public ReceiveBufferSizePredictorFactory getReceiveBufferSizePredictorFactory() {
    174         return predictorFactory;
    175     }
    176
    177     public void setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory predictorFactory) {
    178         if (predictorFactory == null) {
    179             throw new NullPointerException("predictorFactory");
    180         }
    181         this.predictorFactory = predictorFactory;
    182     }
    183 }