1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.channel.nio;
17
18 import io.netty.channel.Channel;
19 import io.netty.channel.EventLoopTaskQueueFactory;
20 import io.netty.channel.IoHandler;
21 import io.netty.channel.SingleThreadIoEventLoop;
22 import io.netty.util.concurrent.RejectedExecutionHandler;
23 import io.netty.util.internal.ObjectUtil;
24 import io.netty.util.internal.PlatformDependent;
25 import io.netty.util.internal.logging.InternalLogger;
26 import io.netty.util.internal.logging.InternalLoggerFactory;
27
28 import java.nio.channels.SelectableChannel;
29 import java.nio.channels.SelectionKey;
30 import java.nio.channels.Selector;
31 import java.nio.channels.spi.SelectorProvider;
32 import java.util.Iterator;
33 import java.util.NoSuchElementException;
34 import java.util.Queue;
35 import java.util.Set;
36 import java.util.concurrent.Executor;
37
38
39
40
41
42
43
44 @Deprecated
45 public final class NioEventLoop extends SingleThreadIoEventLoop {
46
47 private static final InternalLogger logger = InternalLoggerFactory.getInstance(NioEventLoop.class);
48
49 NioEventLoop(NioEventLoopGroup parent, Executor executor, IoHandler ioHandler,
50 EventLoopTaskQueueFactory taskQueueFactory,
51 EventLoopTaskQueueFactory tailTaskQueueFactory, RejectedExecutionHandler rejectedExecutionHandler) {
52 super(parent, executor, ioHandler, newTaskQueue(taskQueueFactory), newTaskQueue(tailTaskQueueFactory),
53 rejectedExecutionHandler);
54 }
55
56 private static Queue<Runnable> newTaskQueue(
57 EventLoopTaskQueueFactory queueFactory) {
58 if (queueFactory == null) {
59 return newTaskQueue0(DEFAULT_MAX_PENDING_TASKS);
60 }
61 return queueFactory.newTaskQueue(DEFAULT_MAX_PENDING_TASKS);
62 }
63
64
65
66
67 public SelectorProvider selectorProvider() {
68 return ((NioIoHandler) ioHandler()).selectorProvider();
69 }
70
71 @Override
72 protected Queue<Runnable> newTaskQueue(int maxPendingTasks) {
73 return newTaskQueue0(maxPendingTasks);
74 }
75
76 private static Queue<Runnable> newTaskQueue0(int maxPendingTasks) {
77
78 return maxPendingTasks == Integer.MAX_VALUE ? PlatformDependent.<Runnable>newMpscQueue()
79 : PlatformDependent.<Runnable>newMpscQueue(maxPendingTasks);
80 }
81
82
83
84
85
86
87 public void register(final SelectableChannel ch, final int interestOps, final NioTask<?> task) {
88 ObjectUtil.checkNotNull(ch, "ch");
89 if (interestOps == 0) {
90 throw new IllegalArgumentException("interestOps must be non-zero.");
91 }
92 if ((interestOps & ~ch.validOps()) != 0) {
93 throw new IllegalArgumentException(
94 "invalid interestOps: " + interestOps + "(validOps: " + ch.validOps() + ')');
95 }
96 ObjectUtil.checkNotNull(task, "task");
97
98 if (isShutdown()) {
99 throw new IllegalStateException("event loop shut down");
100 }
101
102 @SuppressWarnings("unchecked")
103 final NioTask<SelectableChannel> nioTask = (NioTask<SelectableChannel>) task;
104 if (inEventLoop()) {
105 register0(ch, interestOps, nioTask);
106 } else {
107 try {
108
109
110 submit(new Runnable() {
111 @Override
112 public void run() {
113 register0(ch, interestOps, nioTask);
114 }
115 }).sync();
116 } catch (InterruptedException ignore) {
117
118 Thread.currentThread().interrupt();
119 }
120 }
121 }
122
123 private void register0(final SelectableChannel ch, int interestOps, final NioTask<SelectableChannel> task) {
124 try {
125 NioIoRegistration registration = (NioIoRegistration) register(
126 new NioSelectableChannelIoHandle<SelectableChannel>(ch) {
127 @Override
128 protected void handle(SelectableChannel channel, SelectionKey key) {
129 try {
130 task.channelReady(channel, key);
131 } catch (Exception e) {
132 logger.warn("Unexpected exception while running NioTask.channelReady(...)", e);
133 }
134 }
135
136 @Override
137 protected void deregister(SelectableChannel channel) {
138 try {
139 task.channelUnregistered(channel, null);
140 } catch (Exception e) {
141 logger.warn("Unexpected exception while running NioTask.channelUnregistered(...)", e);
142 }
143 }
144 }).get();
145 registration.submit(NioIoOps.valueOf(interestOps));
146 } catch (Exception e) {
147 throw new IllegalStateException(e);
148 }
149 }
150
151
152
153
154 public int getIoRatio() {
155 return 0;
156 }
157
158
159
160
161
162
163 @Deprecated
164 public void setIoRatio(int ioRatio) {
165 logger.debug("NioEventLoop.setIoRatio(int) logic was removed, this is a no-op");
166 }
167
168
169
170
171
172 public void rebuildSelector() {
173 if (!inEventLoop()) {
174 execute(new Runnable() {
175 @Override
176 public void run() {
177 ((NioIoHandler) ioHandler()).rebuildSelector0();
178 }
179 });
180 return;
181 }
182 ((NioIoHandler) ioHandler()).rebuildSelector0();
183 }
184
185 @Override
186 public int registeredChannels() {
187 return ((NioIoHandler) ioHandler()).numRegistered();
188 }
189
190 @Override
191 public Iterator<Channel> registeredChannelsIterator() {
192 assert inEventLoop();
193 final Set<SelectionKey> keys = ((NioIoHandler) ioHandler()).registeredSet();
194 if (keys.isEmpty()) {
195 return ChannelsReadOnlyIterator.empty();
196 }
197 return new Iterator<Channel>() {
198 final Iterator<SelectionKey> selectionKeyIterator =
199 ObjectUtil.checkNotNull(keys, "selectionKeys")
200 .iterator();
201 Channel next;
202 boolean isDone;
203
204 @Override
205 public boolean hasNext() {
206 if (isDone) {
207 return false;
208 }
209 Channel cur = next;
210 if (cur == null) {
211 cur = next = nextOrDone();
212 return cur != null;
213 }
214 return true;
215 }
216
217 @Override
218 public Channel next() {
219 if (isDone) {
220 throw new NoSuchElementException();
221 }
222 Channel cur = next;
223 if (cur == null) {
224 cur = nextOrDone();
225 if (cur == null) {
226 throw new NoSuchElementException();
227 }
228 }
229 next = nextOrDone();
230 return cur;
231 }
232
233 @Override
234 public void remove() {
235 throw new UnsupportedOperationException("remove");
236 }
237
238 private Channel nextOrDone() {
239 Iterator<SelectionKey> it = selectionKeyIterator;
240 while (it.hasNext()) {
241 SelectionKey key = it.next();
242 if (key.isValid()) {
243 Object attachment = key.attachment();
244 if (attachment instanceof NioIoHandler.DefaultNioRegistration) {
245 NioIoHandle handle = ((NioIoHandler.DefaultNioRegistration) attachment).handle();
246 if (handle instanceof AbstractNioChannel.AbstractNioUnsafe) {
247 return ((AbstractNioChannel.AbstractNioUnsafe) handle).channel();
248 }
249 }
250 }
251 }
252 isDone = true;
253 return null;
254 }
255 };
256 }
257
258 Selector unwrappedSelector() {
259 return ((NioIoHandler) ioHandler()).unwrappedSelector();
260 }
261 }