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