View Javadoc
1   /*
2    * Copyright 2015 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 io.netty.channel.epoll;
17  
18  import io.netty.buffer.ByteBufAllocator;
19  import io.netty.channel.ChannelOption;
20  import io.netty.channel.DefaultChannelConfig;
21  import io.netty.channel.MessageSizeEstimator;
22  import io.netty.channel.RecvByteBufAllocator;
23  
24  import java.util.Map;
25  
26  public class EpollChannelConfig extends DefaultChannelConfig {
27      final AbstractEpollChannel channel;
28  
29      EpollChannelConfig(AbstractEpollChannel channel) {
30          super(channel);
31          this.channel = channel;
32      }
33  
34      @Override
35      public Map<ChannelOption<?>, Object> getOptions() {
36          return getOptions(super.getOptions(), EpollChannelOption.EPOLL_MODE);
37      }
38  
39      @SuppressWarnings("unchecked")
40      @Override
41      public <T> T getOption(ChannelOption<T> option) {
42          if (option == EpollChannelOption.EPOLL_MODE) {
43              return (T) getEpollMode();
44          }
45          return super.getOption(option);
46      }
47  
48      @Override
49      public <T> boolean setOption(ChannelOption<T> option, T value) {
50          validate(option, value);
51          if (option == EpollChannelOption.EPOLL_MODE) {
52              setEpollMode((EpollMode) value);
53          } else {
54              return super.setOption(option, value);
55          }
56          return true;
57      }
58  
59      @Override
60      public EpollChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis) {
61          super.setConnectTimeoutMillis(connectTimeoutMillis);
62          return this;
63      }
64  
65      @Override
66      public EpollChannelConfig setMaxMessagesPerRead(int maxMessagesPerRead) {
67          super.setMaxMessagesPerRead(maxMessagesPerRead);
68          return this;
69      }
70  
71      @Override
72      public EpollChannelConfig setWriteSpinCount(int writeSpinCount) {
73          super.setWriteSpinCount(writeSpinCount);
74          return this;
75      }
76  
77      @Override
78      public EpollChannelConfig setAllocator(ByteBufAllocator allocator) {
79          super.setAllocator(allocator);
80          return this;
81      }
82  
83      @Override
84      public EpollChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator) {
85          super.setRecvByteBufAllocator(allocator);
86          return this;
87      }
88  
89      @Override
90      public EpollChannelConfig setAutoRead(boolean autoRead) {
91          super.setAutoRead(autoRead);
92          return this;
93      }
94  
95      @Override
96      public EpollChannelConfig setWriteBufferHighWaterMark(int writeBufferHighWaterMark) {
97          super.setWriteBufferHighWaterMark(writeBufferHighWaterMark);
98          return this;
99      }
100 
101     @Override
102     public EpollChannelConfig setWriteBufferLowWaterMark(int writeBufferLowWaterMark) {
103         super.setWriteBufferLowWaterMark(writeBufferLowWaterMark);
104         return this;
105     }
106 
107     @Override
108     public EpollChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator) {
109         super.setMessageSizeEstimator(estimator);
110         return this;
111     }
112 
113     /**
114      * Return the {@link EpollMode} used. Default is
115      * {@link EpollMode#EDGE_TRIGGERED}. If you want to use {@link #isAutoRead()} {@code false} or
116      * {@link #getMaxMessagesPerRead()} and have an accurate behaviour you should use
117      * {@link EpollMode#LEVEL_TRIGGERED}.
118      */
119     public EpollMode getEpollMode() {
120         return channel.isFlagSet(Native.EPOLLET)
121                 ? EpollMode.EDGE_TRIGGERED : EpollMode.LEVEL_TRIGGERED;
122     }
123 
124     /**
125      * Set the {@link EpollMode} used. Default is
126      * {@link EpollMode#EDGE_TRIGGERED}. If you want to use {@link #isAutoRead()} {@code false} or
127      * {@link #getMaxMessagesPerRead()} and have an accurate behaviour you should use
128      * {@link EpollMode#LEVEL_TRIGGERED}.
129      *
130      * <strong>Be aware this config setting can only be adjusted before the channel was registered.</strong>
131      */
132     public EpollChannelConfig setEpollMode(EpollMode mode) {
133         if (mode == null) {
134             throw new NullPointerException("mode");
135         }
136         switch (mode) {
137             case EDGE_TRIGGERED:
138                 checkChannelNotRegistered();
139                 channel.setFlag(Native.EPOLLET);
140                 break;
141             case LEVEL_TRIGGERED:
142                 checkChannelNotRegistered();
143                 channel.clearFlag(Native.EPOLLET);
144                 break;
145             default:
146                 throw  new Error();
147         }
148         return this;
149     }
150 
151     private void checkChannelNotRegistered() {
152         if (channel.isRegistered()) {
153             throw new IllegalStateException("EpollMode can only be changed before channel is registered");
154         }
155     }
156 
157     @Override
158     protected final void autoReadCleared() {
159         channel.clearEpollIn();
160     }
161 }