View Javadoc

    1   /*
    2    * Copyright 2012 The Netty Project
    3    *
    4    * The Netty Project licenses this file to you under the Apache License,
    5    * version 2.0 (the "License"); you may not use this file except in compliance
    6    * with the 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  class DefaultNioSocketChannelConfig extends DefaultSocketChannelConfig
    34          implements NioSocketChannelConfig {
    35
    36      private static final InternalLogger logger =
    37          InternalLoggerFactory.getInstance(DefaultNioSocketChannelConfig.class);
    38
    39      private static final ReceiveBufferSizePredictorFactory DEFAULT_PREDICTOR_FACTORY =
    40          new AdaptiveReceiveBufferSizePredictorFactory();
    41
    42      private volatile int writeBufferHighWaterMark = 64 * 1024;
    43      private volatile int writeBufferLowWaterMark  = 32 * 1024;
    44      private volatile ReceiveBufferSizePredictor predictor;
    45      private volatile ReceiveBufferSizePredictorFactory predictorFactory = DEFAULT_PREDICTOR_FACTORY;
    46      private volatile int writeSpinCount = 16;
    47
    48      DefaultNioSocketChannelConfig(Socket socket) {
    49          super(socket);
    50      }
    51
    52      @Override
    53      public void setOptions(Map<String, Object> options) {
    54          super.setOptions(options);
    55          if (getWriteBufferHighWaterMark() < getWriteBufferLowWaterMark()) {
    56              // Recover the integrity of the configuration with a sensible value.
    57              setWriteBufferLowWaterMark0(getWriteBufferHighWaterMark() >>> 1);
    58              if (logger.isWarnEnabled()) {
    59                  // Notify the user about misconfiguration.
    60                  logger.warn(
    61                          "writeBufferLowWaterMark cannot be greater than " +
    62                          "writeBufferHighWaterMark; setting to the half of the " +
    63                          "writeBufferHighWaterMark.");
    64              }
    65
    66          }
    67      }
    68
    69      @Override
    70      public boolean setOption(String key, Object value) {
    71          if (super.setOption(key, value)) {
    72              return true;
    73          }
    74
    75          if (key.equals("writeBufferHighWaterMark")) {
    76              setWriteBufferHighWaterMark0(ConversionUtil.toInt(value));
    77          } else if (key.equals("writeBufferLowWaterMark")) {
    78              setWriteBufferLowWaterMark0(ConversionUtil.toInt(value));
    79          } else if (key.equals("writeSpinCount")) {
    80              setWriteSpinCount(ConversionUtil.toInt(value));
    81          } else if (key.equals("receiveBufferSizePredictorFactory")) {
    82              setReceiveBufferSizePredictorFactory((ReceiveBufferSizePredictorFactory) value);
    83          } else if (key.equals("receiveBufferSizePredictor")) {
    84              setReceiveBufferSizePredictor((ReceiveBufferSizePredictor) value);
    85          } else {
    86              return false;
    87          }
    88          return true;
    89      }
    90
    91      public int getWriteBufferHighWaterMark() {
    92          return writeBufferHighWaterMark;
    93      }
    94
    95      public void setWriteBufferHighWaterMark(int writeBufferHighWaterMark) {
    96          if (writeBufferHighWaterMark < getWriteBufferLowWaterMark()) {
    97              throw new IllegalArgumentException(
    98                      "writeBufferHighWaterMark cannot be less than " +
    99                      "writeBufferLowWaterMark (" + getWriteBufferLowWaterMark() + "): " +
    100                     writeBufferHighWaterMark);
    101         }
    102         setWriteBufferHighWaterMark0(writeBufferHighWaterMark);
    103     }
    104
    105     private void setWriteBufferHighWaterMark0(int writeBufferHighWaterMark) {
    106         if (writeBufferHighWaterMark < 0) {
    107             throw new IllegalArgumentException(
    108                     "writeBufferHighWaterMark: " + writeBufferHighWaterMark);
    109         }
    110         this.writeBufferHighWaterMark = writeBufferHighWaterMark;
    111     }
    112
    113     public int getWriteBufferLowWaterMark() {
    114         return writeBufferLowWaterMark;
    115     }
    116
    117     public void setWriteBufferLowWaterMark(int writeBufferLowWaterMark) {
    118         if (writeBufferLowWaterMark > getWriteBufferHighWaterMark()) {
    119             throw new IllegalArgumentException(
    120                     "writeBufferLowWaterMark cannot be greater than " +
    121                     "writeBufferHighWaterMark (" + getWriteBufferHighWaterMark() + "): " +
    122                     writeBufferLowWaterMark);
    123         }
    124         setWriteBufferLowWaterMark0(writeBufferLowWaterMark);
    125     }
    126
    127     private void setWriteBufferLowWaterMark0(int writeBufferLowWaterMark) {
    128         if (writeBufferLowWaterMark < 0) {
    129             throw new IllegalArgumentException(
    130                     "writeBufferLowWaterMark: " + writeBufferLowWaterMark);
    131         }
    132         this.writeBufferLowWaterMark = writeBufferLowWaterMark;
    133     }
    134
    135     public int getWriteSpinCount() {
    136         return writeSpinCount;
    137     }
    138
    139     public void setWriteSpinCount(int writeSpinCount) {
    140         if (writeSpinCount <= 0) {
    141             throw new IllegalArgumentException(
    142                     "writeSpinCount must be a positive integer.");
    143         }
    144         this.writeSpinCount = writeSpinCount;
    145     }
    146
    147     public ReceiveBufferSizePredictor getReceiveBufferSizePredictor() {
    148         ReceiveBufferSizePredictor predictor = this.predictor;
    149         if (predictor == null) {
    150             try {
    151                 this.predictor = predictor = getReceiveBufferSizePredictorFactory().getPredictor();
    152             } catch (Exception e) {
    153                 throw new ChannelException(
    154                         "Failed to create a new " +
    155                         ReceiveBufferSizePredictor.class.getSimpleName() + '.',
    156                         e);
    157             }
    158         }
    159         return predictor;
    160     }
    161
    162     public void setReceiveBufferSizePredictor(
    163             ReceiveBufferSizePredictor predictor) {
    164         if (predictor == null) {
    165             throw new NullPointerException("predictor");
    166         }
    167         this.predictor = predictor;
    168     }
    169
    170     public ReceiveBufferSizePredictorFactory getReceiveBufferSizePredictorFactory() {
    171         return predictorFactory;
    172     }
    173
    174     public void setReceiveBufferSizePredictorFactory(ReceiveBufferSizePredictorFactory predictorFactory) {
    175         if (predictorFactory == null) {
    176             throw new NullPointerException("predictorFactory");
    177         }
    178         this.predictorFactory = predictorFactory;
    179     }
    180 }