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.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, IoHandlerFactory ioHandlerFactory,
50 EventLoopTaskQueueFactory taskQueueFactory,
51 EventLoopTaskQueueFactory tailTaskQueueFactory, RejectedExecutionHandler rejectedExecutionHandler) {
52 super(parent, executor, ioHandlerFactory, 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
72
73
74
75
76 public void register(final SelectableChannel ch, final int interestOps, final NioTask<?> task) {
77 ObjectUtil.checkNotNull(ch, "ch");
78 if (interestOps == 0) {
79 throw new IllegalArgumentException("interestOps must be non-zero.");
80 }
81 if ((interestOps & ~ch.validOps()) != 0) {
82 throw new IllegalArgumentException(
83 "invalid interestOps: " + interestOps + "(validOps: " + ch.validOps() + ')');
84 }
85 ObjectUtil.checkNotNull(task, "task");
86
87 if (isShutdown()) {
88 throw new IllegalStateException("event loop shut down");
89 }
90
91 @SuppressWarnings("unchecked")
92 final NioTask<SelectableChannel> nioTask = (NioTask<SelectableChannel>) task;
93 if (inEventLoop()) {
94 register0(ch, interestOps, nioTask);
95 } else {
96 try {
97
98
99 submit(new Runnable() {
100 @Override
101 public void run() {
102 register0(ch, interestOps, nioTask);
103 }
104 }).sync();
105 } catch (InterruptedException ignore) {
106
107 Thread.currentThread().interrupt();
108 }
109 }
110 }
111
112 private void register0(final SelectableChannel ch, int interestOps, final NioTask<SelectableChannel> task) {
113 try {
114 IoRegistration registration = register(
115 new NioSelectableChannelIoHandle<SelectableChannel>(ch) {
116 @Override
117 protected void handle(SelectableChannel channel, SelectionKey key) {
118 try {
119 task.channelReady(channel, key);
120 } catch (Exception e) {
121 logger.warn("Unexpected exception while running NioTask.channelReady(...)", e);
122 }
123 }
124
125 @Override
126 protected void deregister(SelectableChannel channel) {
127 try {
128 task.channelUnregistered(channel, null);
129 } catch (Exception e) {
130 logger.warn("Unexpected exception while running NioTask.channelUnregistered(...)", e);
131 }
132 }
133 }).get();
134 registration.submit(NioIoOps.valueOf(interestOps));
135 } catch (Exception e) {
136 throw new IllegalStateException(e);
137 }
138 }
139
140
141
142
143 public int getIoRatio() {
144 return 0;
145 }
146
147
148
149
150
151
152 @Deprecated
153 public void setIoRatio(int ioRatio) {
154 logger.debug("NioEventLoop.setIoRatio(int) logic was removed, this is a no-op");
155 }
156
157
158
159
160
161 public void rebuildSelector() {
162 if (!inEventLoop()) {
163 execute(new Runnable() {
164 @Override
165 public void run() {
166 ((NioIoHandler) ioHandler()).rebuildSelector0();
167 }
168 });
169 return;
170 }
171 ((NioIoHandler) ioHandler()).rebuildSelector0();
172 }
173
174 @Override
175 public int registeredChannels() {
176 return ((NioIoHandler) ioHandler()).numRegistered();
177 }
178
179 @Override
180 public Iterator<Channel> registeredChannelsIterator() {
181 assert inEventLoop();
182 final Set<SelectionKey> keys = ((NioIoHandler) ioHandler()).registeredSet();
183 if (keys.isEmpty()) {
184 return ChannelsReadOnlyIterator.empty();
185 }
186 return new Iterator<Channel>() {
187 final Iterator<SelectionKey> selectionKeyIterator =
188 ObjectUtil.checkNotNull(keys, "selectionKeys")
189 .iterator();
190 Channel next;
191 boolean isDone;
192
193 @Override
194 public boolean hasNext() {
195 if (isDone) {
196 return false;
197 }
198 Channel cur = next;
199 if (cur == null) {
200 cur = next = nextOrDone();
201 return cur != null;
202 }
203 return true;
204 }
205
206 @Override
207 public Channel next() {
208 if (isDone) {
209 throw new NoSuchElementException();
210 }
211 Channel cur = next;
212 if (cur == null) {
213 cur = nextOrDone();
214 if (cur == null) {
215 throw new NoSuchElementException();
216 }
217 }
218 next = nextOrDone();
219 return cur;
220 }
221
222 @Override
223 public void remove() {
224 throw new UnsupportedOperationException("remove");
225 }
226
227 private Channel nextOrDone() {
228 Iterator<SelectionKey> it = selectionKeyIterator;
229 while (it.hasNext()) {
230 SelectionKey key = it.next();
231 if (key.isValid()) {
232 Object attachment = key.attachment();
233 if (attachment instanceof NioIoHandler.DefaultNioRegistration) {
234 NioIoHandle handle = ((NioIoHandler.DefaultNioRegistration) attachment).handle();
235 if (handle instanceof AbstractNioChannel.AbstractNioUnsafe) {
236 return ((AbstractNioChannel.AbstractNioUnsafe) handle).channel();
237 }
238 }
239 }
240 }
241 isDone = true;
242 return null;
243 }
244 };
245 }
246
247 Selector unwrappedSelector() {
248 return ((NioIoHandler) ioHandler()).unwrappedSelector();
249 }
250 }