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