1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.channel.nio;
17
18 import io.netty5.channel.IoHandle;
19 import io.netty5.util.internal.logging.InternalLogger;
20 import io.netty5.util.internal.logging.InternalLoggerFactory;
21
22 import java.io.IOException;
23 import java.nio.channels.ClosedChannelException;
24 import java.nio.channels.SelectableChannel;
25 import java.nio.channels.SelectionKey;
26 import java.nio.channels.Selector;
27 import java.util.function.BiConsumer;
28
29 import static java.util.Objects.requireNonNull;
30
31
32
33
34
35
36 public final class NioSelectableChannelHandle<S extends SelectableChannel> implements IoHandle {
37 private static final InternalLogger logger = InternalLoggerFactory.getInstance(NioSelectableChannelHandle.class);
38
39 private final S channel;
40 private final int interestOps;
41 private volatile SelectionKey selectionKey;
42
43 private final BiConsumer<S, SelectionKey> keyProcessor;
44
45 public NioSelectableChannelHandle(S channel, int interestOps, BiConsumer<S, SelectionKey> keyProcessor) {
46 if ((interestOps & ~channel.validOps()) != 0) {
47 throw new IllegalArgumentException(
48 "invalid interestOps: " + interestOps + "(validOps: " + channel.validOps() + ')');
49 }
50 this.channel = requireNonNull(channel, "channel");
51 this.interestOps = interestOps;
52 this.keyProcessor = requireNonNull(keyProcessor, "keyProcessor");
53 }
54
55 @Override
56 public boolean isRegistered() {
57 return channel.isRegistered();
58 }
59
60 private final NioProcessor nioProcessor = new NioProcessor() {
61 @Override
62 public void register(Selector selector) throws ClosedChannelException {
63 int interestOps;
64 SelectionKey key = selectionKey;
65 if (key != null) {
66 interestOps = key.interestOps();
67 key.cancel();
68 } else {
69 interestOps = NioSelectableChannelHandle.this.interestOps;
70 }
71 selectionKey = channel.register(selector, interestOps, this);
72 }
73
74 @Override
75 public void deregister() {
76 SelectionKey key = selectionKey;
77 if (key != null) {
78 key.cancel();
79 }
80 }
81
82 @Override
83 public void handle(SelectionKey key) {
84 keyProcessor.accept(channel, key);
85 }
86
87 @Override
88 public void close() {
89 try {
90 channel.close();
91 } catch (IOException e) {
92 logger.warn("Unexpected exception while closing underlying channel", e);
93 }
94 }
95 };
96
97 NioProcessor nioProcessor() {
98 return nioProcessor;
99 }
100 }