1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.io;
20
21 import java.io.IOException;
22 import java.net.InetSocketAddress;
23 import java.nio.ByteBuffer;
24 import java.util.concurrent.TimeoutException;
25
26 import org.eclipse.jetty.util.Callback;
27 import org.eclipse.jetty.util.log.Log;
28 import org.eclipse.jetty.util.log.Logger;
29 import org.eclipse.jetty.util.thread.Scheduler;
30
31 public abstract class AbstractEndPoint extends IdleTimeout implements EndPoint
32 {
33 private static final Logger LOG = Log.getLogger(AbstractEndPoint.class);
34 private final long _created=System.currentTimeMillis();
35 private final InetSocketAddress _local;
36 private final InetSocketAddress _remote;
37 private volatile Connection _connection;
38
39 private final FillInterest _fillInterest = new FillInterest()
40 {
41 @Override
42 protected boolean needsFill() throws IOException
43 {
44 return AbstractEndPoint.this.needsFill();
45 }
46 };
47
48 private final WriteFlusher _writeFlusher = new WriteFlusher(this)
49 {
50 @Override
51 protected void onIncompleteFlushed()
52 {
53 AbstractEndPoint.this.onIncompleteFlush();
54 }
55 };
56
57 protected AbstractEndPoint(Scheduler scheduler,InetSocketAddress local,InetSocketAddress remote)
58 {
59 super(scheduler);
60 _local=local;
61 _remote=remote;
62 }
63
64 @Override
65 public long getCreatedTimeStamp()
66 {
67 return _created;
68 }
69
70 @Override
71 public InetSocketAddress getLocalAddress()
72 {
73 return _local;
74 }
75
76 @Override
77 public InetSocketAddress getRemoteAddress()
78 {
79 return _remote;
80 }
81
82 @Override
83 public Connection getConnection()
84 {
85 return _connection;
86 }
87
88 @Override
89 public void setConnection(Connection connection)
90 {
91 _connection = connection;
92 }
93
94 @Override
95 public void onOpen()
96 {
97 if (LOG.isDebugEnabled())
98 LOG.debug("onOpen {}",this);
99 super.onOpen();
100 }
101
102 @Override
103 public void onClose()
104 {
105 super.onClose();
106 if (LOG.isDebugEnabled())
107 LOG.debug("onClose {}",this);
108 _writeFlusher.onClose();
109 _fillInterest.onClose();
110 }
111
112 @Override
113 public void close()
114 {
115 onClose();
116 }
117
118 @Override
119 public void fillInterested(Callback callback) throws IllegalStateException
120 {
121 notIdle();
122 _fillInterest.register(callback);
123 }
124
125 @Override
126 public void write(Callback callback, ByteBuffer... buffers) throws IllegalStateException
127 {
128 _writeFlusher.write(callback, buffers);
129 }
130
131 protected abstract void onIncompleteFlush();
132
133 protected abstract boolean needsFill() throws IOException;
134
135 protected FillInterest getFillInterest()
136 {
137 return _fillInterest;
138 }
139
140 protected WriteFlusher getWriteFlusher()
141 {
142 return _writeFlusher;
143 }
144
145 @Override
146 protected void onIdleExpired(TimeoutException timeout)
147 {
148 boolean output_shutdown=isOutputShutdown();
149 boolean input_shutdown=isInputShutdown();
150 boolean fillFailed = _fillInterest.onFail(timeout);
151 boolean writeFailed = _writeFlusher.onFail(timeout);
152
153
154
155
156
157
158
159
160 if (isOpen() && (output_shutdown || input_shutdown) && !(fillFailed || writeFailed))
161 close();
162 else
163 LOG.debug("Ignored idle endpoint {}",this);
164 }
165
166 @Override
167 public String toString()
168 {
169 return String.format("%s@%x{%s<->%d,%s,%s,%s,%s,%s,%d,%s}",
170 getClass().getSimpleName(),
171 hashCode(),
172 getRemoteAddress(),
173 getLocalAddress().getPort(),
174 isOpen()?"Open":"CLOSED",
175 isInputShutdown()?"ISHUT":"in",
176 isOutputShutdown()?"OSHUT":"out",
177 _fillInterest.isInterested()?"R":"-",
178 _writeFlusher.isInProgress()?"W":"-",
179 getIdleTimeout(),
180 getConnection()==null?null:getConnection().getClass().getSimpleName());
181 }
182 }