]> WPIA git - gigi.git/blob - lib/jetty/org/eclipse/jetty/io/AbstractEndPoint.java
8fa2cc86ef98812bcce0d024df0c3dc834f2b6b5
[gigi.git] / lib / jetty / org / eclipse / jetty / io / AbstractEndPoint.java
1 //
2 //  ========================================================================
3 //  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
4 //  ------------------------------------------------------------------------
5 //  All rights reserved. This program and the accompanying materials
6 //  are made available under the terms of the Eclipse Public License v1.0
7 //  and Apache License v2.0 which accompanies this distribution.
8 //
9 //      The Eclipse Public License is available at
10 //      http://www.eclipse.org/legal/epl-v10.html
11 //
12 //      The Apache License v2.0 is available at
13 //      http://www.opensource.org/licenses/apache2.0.php
14 //
15 //  You may elect to redistribute this code under either of these licenses.
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         LOG.debug("onOpen {}",this);
98         super.onOpen();
99     }
100
101     @Override
102     public void onClose()
103     {
104         super.onClose();
105         LOG.debug("onClose {}",this);
106         _writeFlusher.onClose();
107         _fillInterest.onClose();
108     }
109     
110     @Override
111     public void close()
112     {
113         onClose();
114     }
115
116     @Override
117     public void fillInterested(Callback callback) throws IllegalStateException
118     {
119         notIdle();
120         _fillInterest.register(callback);
121     }
122
123     @Override
124     public void write(Callback callback, ByteBuffer... buffers) throws IllegalStateException
125     {
126         _writeFlusher.write(callback, buffers);
127     }
128
129     protected abstract void onIncompleteFlush();
130
131     protected abstract boolean needsFill() throws IOException;
132
133     protected FillInterest getFillInterest()
134     {
135         return _fillInterest;
136     }
137
138     protected WriteFlusher getWriteFlusher()
139     {
140         return _writeFlusher;
141     }
142
143     @Override
144     protected void onIdleExpired(TimeoutException timeout)
145     {
146         boolean output_shutdown=isOutputShutdown();
147         boolean input_shutdown=isInputShutdown();
148         boolean fillFailed = _fillInterest.onFail(timeout);
149         boolean writeFailed = _writeFlusher.onFail(timeout);
150         
151         // If the endpoint is half closed and there was no onFail handling, the close here
152         // This handles the situation where the connection has completed its close handling 
153         // and the endpoint is half closed, but the other party does not complete the close.
154         // This perhaps should not check for half closed, however the servlet spec case allows
155         // for a dispatched servlet or suspended request to extend beyond the connections idle 
156         // time.  So if this test would always close an idle endpoint that is not handled, then 
157         // we would need a mode to ignore timeouts for some HTTP states
158         if (isOpen() && (output_shutdown || input_shutdown) && !(fillFailed || writeFailed))
159             close();
160         else 
161             LOG.debug("Ignored idle endpoint {}",this);
162     }
163
164     @Override
165     public String toString()
166     {
167         return String.format("%s@%x{%s<->%d,%s,%s,%s,%s,%s,%d,%s}",
168                 getClass().getSimpleName(),
169                 hashCode(),
170                 getRemoteAddress(),
171                 getLocalAddress().getPort(),
172                 isOpen()?"Open":"CLOSED",
173                 isInputShutdown()?"ISHUT":"in",
174                 isOutputShutdown()?"OSHUT":"out",
175                 _fillInterest.isInterested()?"R":"-",
176                 _writeFlusher.isInProgress()?"W":"-",
177                 getIdleTimeout(),
178                 getConnection()==null?null:getConnection().getClass().getSimpleName());
179     }
180 }