1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.channel.epoll;
17
18 import io.netty.buffer.ByteBufAllocator;
19 import io.netty.channel.Channel;
20 import io.netty.channel.ChannelException;
21 import io.netty.channel.ChannelOption;
22 import io.netty.channel.DefaultChannelConfig;
23 import io.netty.channel.MessageSizeEstimator;
24 import io.netty.channel.RecvByteBufAllocator;
25 import io.netty.channel.WriteBufferWaterMark;
26 import io.netty.channel.unix.IntegerUnixChannelOption;
27 import io.netty.channel.unix.RawUnixChannelOption;
28 import io.netty.util.internal.ObjectUtil;
29
30 import java.io.IOException;
31 import java.nio.ByteBuffer;
32 import java.util.Map;
33
34 import static io.netty.channel.unix.Limits.SSIZE_MAX;
35
36 public class EpollChannelConfig extends DefaultChannelConfig {
37 private volatile long maxBytesPerGatheringWrite = SSIZE_MAX;
38
39 protected EpollChannelConfig(Channel channel) {
40 super(checkAbstractEpollChannel(channel));
41 }
42
43 protected EpollChannelConfig(Channel channel, RecvByteBufAllocator recvByteBufAllocator) {
44 super(checkAbstractEpollChannel(channel), recvByteBufAllocator);
45 }
46
47 protected LinuxSocket socket() {
48 return ((AbstractEpollChannel) channel).socket;
49 }
50
51 private static Channel checkAbstractEpollChannel(Channel channel) {
52 if (!(channel instanceof AbstractEpollChannel)) {
53 throw new IllegalArgumentException("channel is not AbstractEpollChannel: " + channel.getClass());
54 }
55 return channel;
56 }
57
58 @Override
59 public Map<ChannelOption<?>, Object> getOptions() {
60 return getOptions(super.getOptions(), EpollChannelOption.EPOLL_MODE);
61 }
62
63 @SuppressWarnings("unchecked")
64 @Override
65 public <T> T getOption(ChannelOption<T> option) {
66 if (option == EpollChannelOption.EPOLL_MODE) {
67 return (T) getEpollMode();
68 }
69 try {
70 if (option instanceof IntegerUnixChannelOption) {
71 IntegerUnixChannelOption opt = (IntegerUnixChannelOption) option;
72 return (T) Integer.valueOf(((AbstractEpollChannel) channel).socket.getIntOpt(
73 opt.level(), opt.optname()));
74 }
75 if (option instanceof RawUnixChannelOption) {
76 RawUnixChannelOption opt = (RawUnixChannelOption) option;
77 ByteBuffer out = ByteBuffer.allocate(opt.length());
78 ((AbstractEpollChannel) channel).socket.getRawOpt(opt.level(), opt.optname(), out);
79 return (T) out.flip();
80 }
81 } catch (IOException e) {
82 throw new ChannelException(e);
83 }
84 return super.getOption(option);
85 }
86
87 @Override
88 public <T> boolean setOption(ChannelOption<T> option, T value) {
89 validate(option, value);
90 if (option == EpollChannelOption.EPOLL_MODE) {
91 setEpollMode((EpollMode) value);
92 } else {
93 try {
94 if (option instanceof IntegerUnixChannelOption) {
95 IntegerUnixChannelOption opt = (IntegerUnixChannelOption) option;
96 ((AbstractEpollChannel) channel).socket.setIntOpt(opt.level(), opt.optname(), (Integer) value);
97 return true;
98 } else if (option instanceof RawUnixChannelOption) {
99 RawUnixChannelOption opt = (RawUnixChannelOption) option;
100 ((AbstractEpollChannel) channel).socket.setRawOpt(opt.level(), opt.optname(), (ByteBuffer) value);
101 return true;
102 }
103 } catch (IOException e) {
104 throw new ChannelException(e);
105 }
106 return super.setOption(option, value);
107 }
108 return true;
109 }
110
111 @Override
112 public EpollChannelConfig setConnectTimeoutMillis(int connectTimeoutMillis) {
113 super.setConnectTimeoutMillis(connectTimeoutMillis);
114 return this;
115 }
116
117 @Override
118 @Deprecated
119 public EpollChannelConfig setMaxMessagesPerRead(int maxMessagesPerRead) {
120 super.setMaxMessagesPerRead(maxMessagesPerRead);
121 return this;
122 }
123
124 @Override
125 public EpollChannelConfig setWriteSpinCount(int writeSpinCount) {
126 super.setWriteSpinCount(writeSpinCount);
127 return this;
128 }
129
130 @Override
131 public EpollChannelConfig setAllocator(ByteBufAllocator allocator) {
132 super.setAllocator(allocator);
133 return this;
134 }
135
136 @Override
137 public EpollChannelConfig setRecvByteBufAllocator(RecvByteBufAllocator allocator) {
138 if (!(allocator.newHandle() instanceof RecvByteBufAllocator.ExtendedHandle)) {
139 throw new IllegalArgumentException("allocator.newHandle() must return an object of type: " +
140 RecvByteBufAllocator.ExtendedHandle.class);
141 }
142 super.setRecvByteBufAllocator(allocator);
143 return this;
144 }
145
146 @Override
147 public EpollChannelConfig setAutoRead(boolean autoRead) {
148 super.setAutoRead(autoRead);
149 return this;
150 }
151
152 @Override
153 @Deprecated
154 public EpollChannelConfig setWriteBufferHighWaterMark(int writeBufferHighWaterMark) {
155 super.setWriteBufferHighWaterMark(writeBufferHighWaterMark);
156 return this;
157 }
158
159 @Override
160 @Deprecated
161 public EpollChannelConfig setWriteBufferLowWaterMark(int writeBufferLowWaterMark) {
162 super.setWriteBufferLowWaterMark(writeBufferLowWaterMark);
163 return this;
164 }
165
166 @Override
167 public EpollChannelConfig setWriteBufferWaterMark(WriteBufferWaterMark writeBufferWaterMark) {
168 super.setWriteBufferWaterMark(writeBufferWaterMark);
169 return this;
170 }
171
172 @Override
173 public EpollChannelConfig setMessageSizeEstimator(MessageSizeEstimator estimator) {
174 super.setMessageSizeEstimator(estimator);
175 return this;
176 }
177
178
179
180
181
182
183
184 public EpollMode getEpollMode() {
185 return ((AbstractEpollChannel) channel).isFlagSet(Native.EPOLLET)
186 ? EpollMode.EDGE_TRIGGERED : EpollMode.LEVEL_TRIGGERED;
187 }
188
189
190
191
192
193
194
195
196
197 public EpollChannelConfig setEpollMode(EpollMode mode) {
198 ObjectUtil.checkNotNull(mode, "mode");
199
200 try {
201 switch (mode) {
202 case EDGE_TRIGGERED:
203 checkChannelNotRegistered();
204 ((AbstractEpollChannel) channel).setFlag(Native.EPOLLET);
205 break;
206 case LEVEL_TRIGGERED:
207 checkChannelNotRegistered();
208 ((AbstractEpollChannel) channel).clearFlag(Native.EPOLLET);
209 break;
210 default:
211 throw new Error();
212 }
213 } catch (IOException e) {
214 throw new ChannelException(e);
215 }
216 return this;
217 }
218
219 private void checkChannelNotRegistered() {
220 if (channel.isRegistered()) {
221 throw new IllegalStateException("EpollMode can only be changed before channel is registered");
222 }
223 }
224
225 @Override
226 protected final void autoReadCleared() {
227 ((AbstractEpollChannel) channel).clearEpollIn();
228 }
229
230 protected final void setMaxBytesPerGatheringWrite(long maxBytesPerGatheringWrite) {
231 this.maxBytesPerGatheringWrite = maxBytesPerGatheringWrite;
232 }
233
234 protected final long getMaxBytesPerGatheringWrite() {
235 return maxBytesPerGatheringWrite;
236 }
237 }