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
144 public void rebuildSelector() {
145 if (!inEventLoop()) {
146 execute(new Runnable() {
147 @Override
148 public void run() {
149 ((NioIoHandler) ioHandler()).rebuildSelector0();
150 }
151 });
152 return;
153 }
154 ((NioIoHandler) ioHandler()).rebuildSelector0();
155 }
156
157 @Override
158 public int registeredChannels() {
159 return ((NioIoHandler) ioHandler()).numRegistered();
160 }
161
162 @Override
163 public Iterator<Channel> registeredChannelsIterator() {
164 assert inEventLoop();
165 final Set<SelectionKey> keys = ((NioIoHandler) ioHandler()).registeredSet();
166 if (keys.isEmpty()) {
167 return ChannelsReadOnlyIterator.empty();
168 }
169 return new Iterator<Channel>() {
170 final Iterator<SelectionKey> selectionKeyIterator =
171 ObjectUtil.checkNotNull(keys, "selectionKeys")
172 .iterator();
173 Channel next;
174 boolean isDone;
175
176 @Override
177 public boolean hasNext() {
178 if (isDone) {
179 return false;
180 }
181 Channel cur = next;
182 if (cur == null) {
183 cur = next = nextOrDone();
184 return cur != null;
185 }
186 return true;
187 }
188
189 @Override
190 public Channel next() {
191 if (isDone) {
192 throw new NoSuchElementException();
193 }
194 Channel cur = next;
195 if (cur == null) {
196 cur = nextOrDone();
197 if (cur == null) {
198 throw new NoSuchElementException();
199 }
200 }
201 next = nextOrDone();
202 return cur;
203 }
204
205 @Override
206 public void remove() {
207 throw new UnsupportedOperationException("remove");
208 }
209
210 private Channel nextOrDone() {
211 Iterator<SelectionKey> it = selectionKeyIterator;
212 while (it.hasNext()) {
213 SelectionKey key = it.next();
214 if (key.isValid()) {
215 Object attachment = key.attachment();
216 if (attachment instanceof NioIoHandler.DefaultNioRegistration) {
217 NioIoHandle handle = ((NioIoHandler.DefaultNioRegistration) attachment).handle();
218 if (handle instanceof AbstractNioChannel.AbstractNioUnsafe) {
219 return ((AbstractNioChannel.AbstractNioUnsafe) handle).channel();
220 }
221 }
222 }
223 }
224 isDone = true;
225 return null;
226 }
227 };
228 }
229
230 Selector unwrappedSelector() {
231 return ((NioIoHandler) ioHandler()).unwrappedSelector();
232 }
233 }