1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package io.netty.channel.oio;
17
18 import io.netty.channel.AbstractChannel;
19 import io.netty.channel.Channel;
20 import io.netty.channel.ChannelPromise;
21 import io.netty.channel.EventLoop;
22 import io.netty.channel.ThreadPerChannelEventLoop;
23 import io.netty.util.internal.OneTimeTask;
24
25 import java.net.SocketAddress;
26
27
28
29
30 public abstract class AbstractOioChannel extends AbstractChannel {
31
32 protected static final int SO_TIMEOUT = 1000;
33
34 boolean readPending;
35 private final Runnable readTask = new Runnable() {
36 @Override
37 public void run() {
38 doRead();
39 }
40 };
41 private final Runnable clearReadPendingRunnable = new Runnable() {
42 @Override
43 public void run() {
44 readPending = false;
45 }
46 };
47
48
49
50
51 protected AbstractOioChannel(Channel parent) {
52 super(parent);
53 }
54
55 @Override
56 protected AbstractUnsafe newUnsafe() {
57 return new DefaultOioUnsafe();
58 }
59
60 private final class DefaultOioUnsafe extends AbstractUnsafe {
61 @Override
62 public void connect(
63 final SocketAddress remoteAddress,
64 final SocketAddress localAddress, final ChannelPromise promise) {
65 if (!promise.setUncancellable() || !ensureOpen(promise)) {
66 return;
67 }
68
69 try {
70 boolean wasActive = isActive();
71 doConnect(remoteAddress, localAddress);
72 safeSetSuccess(promise);
73 if (!wasActive && isActive()) {
74 pipeline().fireChannelActive();
75 }
76 } catch (Throwable t) {
77 safeSetFailure(promise, annotateConnectException(t, remoteAddress));
78 closeIfClosed();
79 }
80 }
81 }
82
83 @Override
84 protected boolean isCompatible(EventLoop loop) {
85 return loop instanceof ThreadPerChannelEventLoop;
86 }
87
88
89
90
91 protected abstract void doConnect(
92 SocketAddress remoteAddress, SocketAddress localAddress) throws Exception;
93
94 @Override
95 protected void doBeginRead() throws Exception {
96 if (readPending) {
97 return;
98 }
99
100 readPending = true;
101 eventLoop().execute(readTask);
102 }
103
104 protected abstract void doRead();
105
106
107
108
109
110 @Deprecated
111 protected boolean isReadPending() {
112 return readPending;
113 }
114
115
116
117
118
119 @Deprecated
120 protected void setReadPending(final boolean readPending) {
121 if (isRegistered()) {
122 EventLoop eventLoop = eventLoop();
123 if (eventLoop.inEventLoop()) {
124 this.readPending = readPending;
125 } else {
126 eventLoop.execute(new OneTimeTask() {
127 @Override
128 public void run() {
129 AbstractOioChannel.this.readPending = readPending;
130 }
131 });
132 }
133 } else {
134 this.readPending = readPending;
135 }
136 }
137
138
139
140
141 protected final void clearReadPending() {
142 if (isRegistered()) {
143 EventLoop eventLoop = eventLoop();
144 if (eventLoop.inEventLoop()) {
145 readPending = false;
146 } else {
147 eventLoop.execute(clearReadPendingRunnable);
148 }
149 } else {
150
151 readPending = false;
152 }
153 }
154 }