1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty5.channel.local;
17
18 import io.netty5.channel.Channel;
19 import io.netty5.channel.IoExecutionContext;
20 import io.netty5.channel.IoHandle;
21 import io.netty5.channel.IoHandler;
22 import io.netty5.channel.IoHandlerFactory;
23 import io.netty5.util.internal.StringUtil;
24
25 import java.util.HashSet;
26 import java.util.Set;
27 import java.util.concurrent.locks.LockSupport;
28
29
30
31
32 public final class LocalHandler implements IoHandler {
33 private final Set<LocalChannelUnsafe> registeredChannels = new HashSet<>(64);
34 private volatile Thread executionThread;
35
36 private LocalHandler() { }
37
38
39
40
41 public static IoHandlerFactory newFactory() {
42 return LocalHandler::new;
43 }
44
45 private static LocalChannelUnsafe cast(IoHandle handle) {
46 if (handle instanceof LocalChannelUnsafe) {
47 return (LocalChannelUnsafe) handle;
48 }
49 throw new IllegalArgumentException("IoHandle of type " + StringUtil.simpleClassName(handle) + " not supported");
50 }
51
52 @Override
53 public int run(IoExecutionContext runner) {
54 if (executionThread == null) {
55 executionThread = Thread.currentThread();
56 }
57 if (runner.canBlock()) {
58
59 LockSupport.parkNanos(this, runner.delayNanos(System.nanoTime()));
60 }
61 return 0;
62 }
63
64 @Override
65 public void wakeup(boolean inEventLoop) {
66 if (!inEventLoop) {
67 Thread thread = executionThread;
68 if (thread != null) {
69
70 LockSupport.unpark(thread);
71 }
72 }
73 }
74
75 @Override
76 public void prepareToDestroy() {
77 for (LocalChannelUnsafe unsafe : registeredChannels) {
78 unsafe.closeTransportNow();
79 }
80 registeredChannels.clear();
81 }
82
83 @Override
84 public void destroy() {
85 }
86
87 @Override
88 public void register(IoHandle handle) {
89 LocalChannelUnsafe unsafe = cast(handle);
90 if (registeredChannels.add(unsafe)) {
91 unsafe.registerTransportNow();
92 }
93 }
94
95 @Override
96 public void deregister(IoHandle handle) {
97 LocalChannelUnsafe unsafe = cast(handle);
98 if (registeredChannels.remove(unsafe)) {
99 unsafe.deregisterTransportNow();
100 }
101 }
102
103 @Override
104 public boolean isCompatible(Class<? extends IoHandle> handleType) {
105 return LocalChannelUnsafe.class.isAssignableFrom(handleType);
106 }
107 }