103928aee4356845252ac6b662d5c72c29903813eJake Slack// 203928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 303928aee4356845252ac6b662d5c72c29903813eJake Slack// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. 403928aee4356845252ac6b662d5c72c29903813eJake Slack// ------------------------------------------------------------------------ 503928aee4356845252ac6b662d5c72c29903813eJake Slack// All rights reserved. This program and the accompanying materials 603928aee4356845252ac6b662d5c72c29903813eJake Slack// are made available under the terms of the Eclipse Public License v1.0 703928aee4356845252ac6b662d5c72c29903813eJake Slack// and Apache License v2.0 which accompanies this distribution. 803928aee4356845252ac6b662d5c72c29903813eJake Slack// 903928aee4356845252ac6b662d5c72c29903813eJake Slack// The Eclipse Public License is available at 1003928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.eclipse.org/legal/epl-v10.html 1103928aee4356845252ac6b662d5c72c29903813eJake Slack// 1203928aee4356845252ac6b662d5c72c29903813eJake Slack// The Apache License v2.0 is available at 1303928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.opensource.org/licenses/apache2.0.php 1403928aee4356845252ac6b662d5c72c29903813eJake Slack// 1503928aee4356845252ac6b662d5c72c29903813eJake Slack// You may elect to redistribute this code under either of these licenses. 1603928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 1703928aee4356845252ac6b662d5c72c29903813eJake Slack// 1803928aee4356845252ac6b662d5c72c29903813eJake Slack 1903928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.server.nio; 2003928aee4356845252ac6b662d5c72c29903813eJake Slack 2103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.IOException; 2203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.net.InetSocketAddress; 2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.net.Socket; 2403928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.nio.channels.ByteChannel; 2503928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.nio.channels.SelectionKey; 2603928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.nio.channels.ServerSocketChannel; 2703928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.nio.channels.SocketChannel; 2803928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Set; 2903928aee4356845252ac6b662d5c72c29903813eJake Slack 3003928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.http.HttpException; 3103928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.Buffer; 3203928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.ConnectedEndPoint; 3303928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.Connection; 3403928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.EndPoint; 3503928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.EofException; 3603928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.io.nio.ChannelEndPoint; 3703928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.BlockingHttpConnection; 3803928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.Request; 3903928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.ConcurrentHashSet; 4003928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Log; 4103928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Logger; 4203928aee4356845252ac6b662d5c72c29903813eJake Slack 4303928aee4356845252ac6b662d5c72c29903813eJake Slack 4403928aee4356845252ac6b662d5c72c29903813eJake Slack/* ------------------------------------------------------------------------------- */ 4503928aee4356845252ac6b662d5c72c29903813eJake Slack/** Blocking NIO connector. 4603928aee4356845252ac6b662d5c72c29903813eJake Slack * This connector uses efficient NIO buffers with a traditional blocking thread model. 4703928aee4356845252ac6b662d5c72c29903813eJake Slack * Direct NIO buffers are used and a thread is allocated per connections. 4803928aee4356845252ac6b662d5c72c29903813eJake Slack * 4903928aee4356845252ac6b662d5c72c29903813eJake Slack * This connector is best used when there are a few very active connections. 5003928aee4356845252ac6b662d5c72c29903813eJake Slack * 5103928aee4356845252ac6b662d5c72c29903813eJake Slack * @org.apache.xbean.XBean element="blockingNioConnector" description="Creates a blocking NIO based socket connector" 5203928aee4356845252ac6b662d5c72c29903813eJake Slack * 5303928aee4356845252ac6b662d5c72c29903813eJake Slack * 5403928aee4356845252ac6b662d5c72c29903813eJake Slack * 5503928aee4356845252ac6b662d5c72c29903813eJake Slack */ 5603928aee4356845252ac6b662d5c72c29903813eJake Slackpublic class BlockingChannelConnector extends AbstractNIOConnector 5703928aee4356845252ac6b662d5c72c29903813eJake Slack{ 5803928aee4356845252ac6b662d5c72c29903813eJake Slack private static final Logger LOG = Log.getLogger(BlockingChannelConnector.class); 5903928aee4356845252ac6b662d5c72c29903813eJake Slack 6003928aee4356845252ac6b662d5c72c29903813eJake Slack private transient ServerSocketChannel _acceptChannel; 6103928aee4356845252ac6b662d5c72c29903813eJake Slack private final Set<BlockingChannelEndPoint> _endpoints = new ConcurrentHashSet<BlockingChannelEndPoint>(); 6203928aee4356845252ac6b662d5c72c29903813eJake Slack 6303928aee4356845252ac6b662d5c72c29903813eJake Slack 6403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 6503928aee4356845252ac6b662d5c72c29903813eJake Slack /** Constructor. 6603928aee4356845252ac6b662d5c72c29903813eJake Slack * 6703928aee4356845252ac6b662d5c72c29903813eJake Slack */ 6803928aee4356845252ac6b662d5c72c29903813eJake Slack public BlockingChannelConnector() 6903928aee4356845252ac6b662d5c72c29903813eJake Slack { 7003928aee4356845252ac6b662d5c72c29903813eJake Slack } 7103928aee4356845252ac6b662d5c72c29903813eJake Slack 7203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 7303928aee4356845252ac6b662d5c72c29903813eJake Slack public Object getConnection() 7403928aee4356845252ac6b662d5c72c29903813eJake Slack { 7503928aee4356845252ac6b662d5c72c29903813eJake Slack return _acceptChannel; 7603928aee4356845252ac6b662d5c72c29903813eJake Slack } 7703928aee4356845252ac6b662d5c72c29903813eJake Slack 7803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 7903928aee4356845252ac6b662d5c72c29903813eJake Slack /** 8003928aee4356845252ac6b662d5c72c29903813eJake Slack * @see org.eclipse.jetty.server.AbstractConnector#doStart() 8103928aee4356845252ac6b662d5c72c29903813eJake Slack */ 8203928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 8303928aee4356845252ac6b662d5c72c29903813eJake Slack protected void doStart() throws Exception 8403928aee4356845252ac6b662d5c72c29903813eJake Slack { 8503928aee4356845252ac6b662d5c72c29903813eJake Slack super.doStart(); 8603928aee4356845252ac6b662d5c72c29903813eJake Slack getThreadPool().dispatch(new Runnable() 8703928aee4356845252ac6b662d5c72c29903813eJake Slack { 8803928aee4356845252ac6b662d5c72c29903813eJake Slack 8903928aee4356845252ac6b662d5c72c29903813eJake Slack public void run() 9003928aee4356845252ac6b662d5c72c29903813eJake Slack { 9103928aee4356845252ac6b662d5c72c29903813eJake Slack while (isRunning()) 9203928aee4356845252ac6b662d5c72c29903813eJake Slack { 9303928aee4356845252ac6b662d5c72c29903813eJake Slack try 9403928aee4356845252ac6b662d5c72c29903813eJake Slack { 9503928aee4356845252ac6b662d5c72c29903813eJake Slack Thread.sleep(400); 9603928aee4356845252ac6b662d5c72c29903813eJake Slack long now=System.currentTimeMillis(); 9703928aee4356845252ac6b662d5c72c29903813eJake Slack for (BlockingChannelEndPoint endp : _endpoints) 9803928aee4356845252ac6b662d5c72c29903813eJake Slack { 9903928aee4356845252ac6b662d5c72c29903813eJake Slack endp.checkIdleTimestamp(now); 10003928aee4356845252ac6b662d5c72c29903813eJake Slack } 10103928aee4356845252ac6b662d5c72c29903813eJake Slack } 10203928aee4356845252ac6b662d5c72c29903813eJake Slack catch(InterruptedException e) 10303928aee4356845252ac6b662d5c72c29903813eJake Slack { 10403928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 10503928aee4356845252ac6b662d5c72c29903813eJake Slack } 10603928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) 10703928aee4356845252ac6b662d5c72c29903813eJake Slack { 10803928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn(e); 10903928aee4356845252ac6b662d5c72c29903813eJake Slack } 11003928aee4356845252ac6b662d5c72c29903813eJake Slack } 11103928aee4356845252ac6b662d5c72c29903813eJake Slack } 11203928aee4356845252ac6b662d5c72c29903813eJake Slack 11303928aee4356845252ac6b662d5c72c29903813eJake Slack }); 11403928aee4356845252ac6b662d5c72c29903813eJake Slack 11503928aee4356845252ac6b662d5c72c29903813eJake Slack } 11603928aee4356845252ac6b662d5c72c29903813eJake Slack 11703928aee4356845252ac6b662d5c72c29903813eJake Slack 11803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 11903928aee4356845252ac6b662d5c72c29903813eJake Slack public void open() throws IOException 12003928aee4356845252ac6b662d5c72c29903813eJake Slack { 12103928aee4356845252ac6b662d5c72c29903813eJake Slack // Create a new server socket and set to non blocking mode 12203928aee4356845252ac6b662d5c72c29903813eJake Slack _acceptChannel= ServerSocketChannel.open(); 12303928aee4356845252ac6b662d5c72c29903813eJake Slack _acceptChannel.configureBlocking(true); 12403928aee4356845252ac6b662d5c72c29903813eJake Slack 12503928aee4356845252ac6b662d5c72c29903813eJake Slack // Bind the server socket to the local host and port 12603928aee4356845252ac6b662d5c72c29903813eJake Slack InetSocketAddress addr = getHost()==null?new InetSocketAddress(getPort()):new InetSocketAddress(getHost(),getPort()); 12703928aee4356845252ac6b662d5c72c29903813eJake Slack _acceptChannel.socket().bind(addr,getAcceptQueueSize()); 12803928aee4356845252ac6b662d5c72c29903813eJake Slack } 12903928aee4356845252ac6b662d5c72c29903813eJake Slack 13003928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 13103928aee4356845252ac6b662d5c72c29903813eJake Slack public void close() throws IOException 13203928aee4356845252ac6b662d5c72c29903813eJake Slack { 13303928aee4356845252ac6b662d5c72c29903813eJake Slack if (_acceptChannel != null) 13403928aee4356845252ac6b662d5c72c29903813eJake Slack _acceptChannel.close(); 13503928aee4356845252ac6b662d5c72c29903813eJake Slack _acceptChannel=null; 13603928aee4356845252ac6b662d5c72c29903813eJake Slack } 13703928aee4356845252ac6b662d5c72c29903813eJake Slack 13803928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 13903928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 14003928aee4356845252ac6b662d5c72c29903813eJake Slack public void accept(int acceptorID) 14103928aee4356845252ac6b662d5c72c29903813eJake Slack throws IOException, InterruptedException 14203928aee4356845252ac6b662d5c72c29903813eJake Slack { 14303928aee4356845252ac6b662d5c72c29903813eJake Slack SocketChannel channel = _acceptChannel.accept(); 14403928aee4356845252ac6b662d5c72c29903813eJake Slack channel.configureBlocking(true); 14503928aee4356845252ac6b662d5c72c29903813eJake Slack Socket socket=channel.socket(); 14603928aee4356845252ac6b662d5c72c29903813eJake Slack configure(socket); 14703928aee4356845252ac6b662d5c72c29903813eJake Slack 14803928aee4356845252ac6b662d5c72c29903813eJake Slack BlockingChannelEndPoint connection=new BlockingChannelEndPoint(channel); 14903928aee4356845252ac6b662d5c72c29903813eJake Slack connection.dispatch(); 15003928aee4356845252ac6b662d5c72c29903813eJake Slack } 15103928aee4356845252ac6b662d5c72c29903813eJake Slack 15203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 15303928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 15403928aee4356845252ac6b662d5c72c29903813eJake Slack public void customize(EndPoint endpoint, Request request) 15503928aee4356845252ac6b662d5c72c29903813eJake Slack throws IOException 15603928aee4356845252ac6b662d5c72c29903813eJake Slack { 15703928aee4356845252ac6b662d5c72c29903813eJake Slack super.customize(endpoint, request); 15803928aee4356845252ac6b662d5c72c29903813eJake Slack endpoint.setMaxIdleTime(_maxIdleTime); 15903928aee4356845252ac6b662d5c72c29903813eJake Slack configure(((SocketChannel)endpoint.getTransport()).socket()); 16003928aee4356845252ac6b662d5c72c29903813eJake Slack } 16103928aee4356845252ac6b662d5c72c29903813eJake Slack 16203928aee4356845252ac6b662d5c72c29903813eJake Slack 16303928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 16403928aee4356845252ac6b662d5c72c29903813eJake Slack public int getLocalPort() 16503928aee4356845252ac6b662d5c72c29903813eJake Slack { 16603928aee4356845252ac6b662d5c72c29903813eJake Slack if (_acceptChannel==null || !_acceptChannel.isOpen()) 16703928aee4356845252ac6b662d5c72c29903813eJake Slack return -1; 16803928aee4356845252ac6b662d5c72c29903813eJake Slack return _acceptChannel.socket().getLocalPort(); 16903928aee4356845252ac6b662d5c72c29903813eJake Slack } 17003928aee4356845252ac6b662d5c72c29903813eJake Slack 17103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 17203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 17303928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------------------------- */ 17403928aee4356845252ac6b662d5c72c29903813eJake Slack private class BlockingChannelEndPoint extends ChannelEndPoint implements Runnable, ConnectedEndPoint 17503928aee4356845252ac6b662d5c72c29903813eJake Slack { 17603928aee4356845252ac6b662d5c72c29903813eJake Slack private Connection _connection; 17703928aee4356845252ac6b662d5c72c29903813eJake Slack private int _timeout; 17803928aee4356845252ac6b662d5c72c29903813eJake Slack private volatile long _idleTimestamp; 17903928aee4356845252ac6b662d5c72c29903813eJake Slack 18003928aee4356845252ac6b662d5c72c29903813eJake Slack BlockingChannelEndPoint(ByteChannel channel) 18103928aee4356845252ac6b662d5c72c29903813eJake Slack throws IOException 18203928aee4356845252ac6b662d5c72c29903813eJake Slack { 18303928aee4356845252ac6b662d5c72c29903813eJake Slack super(channel,BlockingChannelConnector.this._maxIdleTime); 18403928aee4356845252ac6b662d5c72c29903813eJake Slack _connection = new BlockingHttpConnection(BlockingChannelConnector.this,this,getServer()); 18503928aee4356845252ac6b662d5c72c29903813eJake Slack } 18603928aee4356845252ac6b662d5c72c29903813eJake Slack 18703928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 18803928aee4356845252ac6b662d5c72c29903813eJake Slack /** Get the connection. 18903928aee4356845252ac6b662d5c72c29903813eJake Slack * @return the connection 19003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 19103928aee4356845252ac6b662d5c72c29903813eJake Slack public Connection getConnection() 19203928aee4356845252ac6b662d5c72c29903813eJake Slack { 19303928aee4356845252ac6b662d5c72c29903813eJake Slack return _connection; 19403928aee4356845252ac6b662d5c72c29903813eJake Slack } 19503928aee4356845252ac6b662d5c72c29903813eJake Slack 19603928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 19703928aee4356845252ac6b662d5c72c29903813eJake Slack public void setConnection(Connection connection) 19803928aee4356845252ac6b662d5c72c29903813eJake Slack { 19903928aee4356845252ac6b662d5c72c29903813eJake Slack _connection=connection; 20003928aee4356845252ac6b662d5c72c29903813eJake Slack } 20103928aee4356845252ac6b662d5c72c29903813eJake Slack 20203928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 20303928aee4356845252ac6b662d5c72c29903813eJake Slack public void checkIdleTimestamp(long now) 20403928aee4356845252ac6b662d5c72c29903813eJake Slack { 20503928aee4356845252ac6b662d5c72c29903813eJake Slack if (_idleTimestamp!=0 && _timeout>0 && now>(_idleTimestamp+_timeout)) 20603928aee4356845252ac6b662d5c72c29903813eJake Slack { 20703928aee4356845252ac6b662d5c72c29903813eJake Slack idleExpired(); 20803928aee4356845252ac6b662d5c72c29903813eJake Slack } 20903928aee4356845252ac6b662d5c72c29903813eJake Slack } 21003928aee4356845252ac6b662d5c72c29903813eJake Slack 21103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 21203928aee4356845252ac6b662d5c72c29903813eJake Slack protected void idleExpired() 21303928aee4356845252ac6b662d5c72c29903813eJake Slack { 21403928aee4356845252ac6b662d5c72c29903813eJake Slack try 21503928aee4356845252ac6b662d5c72c29903813eJake Slack { 21603928aee4356845252ac6b662d5c72c29903813eJake Slack super.close(); 21703928aee4356845252ac6b662d5c72c29903813eJake Slack } 21803928aee4356845252ac6b662d5c72c29903813eJake Slack catch (IOException e) 21903928aee4356845252ac6b662d5c72c29903813eJake Slack { 22003928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 22103928aee4356845252ac6b662d5c72c29903813eJake Slack } 22203928aee4356845252ac6b662d5c72c29903813eJake Slack } 22303928aee4356845252ac6b662d5c72c29903813eJake Slack 22403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 22503928aee4356845252ac6b662d5c72c29903813eJake Slack void dispatch() throws IOException 22603928aee4356845252ac6b662d5c72c29903813eJake Slack { 22703928aee4356845252ac6b662d5c72c29903813eJake Slack if (!getThreadPool().dispatch(this)) 22803928aee4356845252ac6b662d5c72c29903813eJake Slack { 22903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("dispatch failed for {}",_connection); 23003928aee4356845252ac6b662d5c72c29903813eJake Slack super.close(); 23103928aee4356845252ac6b662d5c72c29903813eJake Slack } 23203928aee4356845252ac6b662d5c72c29903813eJake Slack } 23303928aee4356845252ac6b662d5c72c29903813eJake Slack 23403928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 23503928aee4356845252ac6b662d5c72c29903813eJake Slack /** 23603928aee4356845252ac6b662d5c72c29903813eJake Slack * @see org.eclipse.jetty.io.nio.ChannelEndPoint#fill(org.eclipse.jetty.io.Buffer) 23703928aee4356845252ac6b662d5c72c29903813eJake Slack */ 23803928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 23903928aee4356845252ac6b662d5c72c29903813eJake Slack public int fill(Buffer buffer) throws IOException 24003928aee4356845252ac6b662d5c72c29903813eJake Slack { 24103928aee4356845252ac6b662d5c72c29903813eJake Slack _idleTimestamp=System.currentTimeMillis(); 24203928aee4356845252ac6b662d5c72c29903813eJake Slack return super.fill(buffer); 24303928aee4356845252ac6b662d5c72c29903813eJake Slack } 24403928aee4356845252ac6b662d5c72c29903813eJake Slack 24503928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 24603928aee4356845252ac6b662d5c72c29903813eJake Slack /** 24703928aee4356845252ac6b662d5c72c29903813eJake Slack * @see org.eclipse.jetty.io.nio.ChannelEndPoint#flush(org.eclipse.jetty.io.Buffer) 24803928aee4356845252ac6b662d5c72c29903813eJake Slack */ 24903928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 25003928aee4356845252ac6b662d5c72c29903813eJake Slack public int flush(Buffer buffer) throws IOException 25103928aee4356845252ac6b662d5c72c29903813eJake Slack { 25203928aee4356845252ac6b662d5c72c29903813eJake Slack _idleTimestamp=System.currentTimeMillis(); 25303928aee4356845252ac6b662d5c72c29903813eJake Slack return super.flush(buffer); 25403928aee4356845252ac6b662d5c72c29903813eJake Slack } 25503928aee4356845252ac6b662d5c72c29903813eJake Slack 25603928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 25703928aee4356845252ac6b662d5c72c29903813eJake Slack /** 25803928aee4356845252ac6b662d5c72c29903813eJake Slack * @see org.eclipse.jetty.io.nio.ChannelEndPoint#flush(org.eclipse.jetty.io.Buffer, org.eclipse.jetty.io.Buffer, org.eclipse.jetty.io.Buffer) 25903928aee4356845252ac6b662d5c72c29903813eJake Slack */ 26003928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 26103928aee4356845252ac6b662d5c72c29903813eJake Slack public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException 26203928aee4356845252ac6b662d5c72c29903813eJake Slack { 26303928aee4356845252ac6b662d5c72c29903813eJake Slack _idleTimestamp=System.currentTimeMillis(); 26403928aee4356845252ac6b662d5c72c29903813eJake Slack return super.flush(header,buffer,trailer); 26503928aee4356845252ac6b662d5c72c29903813eJake Slack } 26603928aee4356845252ac6b662d5c72c29903813eJake Slack 26703928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 26803928aee4356845252ac6b662d5c72c29903813eJake Slack public void run() 26903928aee4356845252ac6b662d5c72c29903813eJake Slack { 27003928aee4356845252ac6b662d5c72c29903813eJake Slack try 27103928aee4356845252ac6b662d5c72c29903813eJake Slack { 27203928aee4356845252ac6b662d5c72c29903813eJake Slack _timeout=getMaxIdleTime(); 27303928aee4356845252ac6b662d5c72c29903813eJake Slack connectionOpened(_connection); 27403928aee4356845252ac6b662d5c72c29903813eJake Slack _endpoints.add(this); 27503928aee4356845252ac6b662d5c72c29903813eJake Slack 27603928aee4356845252ac6b662d5c72c29903813eJake Slack while (isOpen()) 27703928aee4356845252ac6b662d5c72c29903813eJake Slack { 27803928aee4356845252ac6b662d5c72c29903813eJake Slack _idleTimestamp=System.currentTimeMillis(); 27903928aee4356845252ac6b662d5c72c29903813eJake Slack if (_connection.isIdle()) 28003928aee4356845252ac6b662d5c72c29903813eJake Slack { 28103928aee4356845252ac6b662d5c72c29903813eJake Slack if (getServer().getThreadPool().isLowOnThreads()) 28203928aee4356845252ac6b662d5c72c29903813eJake Slack { 28303928aee4356845252ac6b662d5c72c29903813eJake Slack int lrmit = getLowResourcesMaxIdleTime(); 28403928aee4356845252ac6b662d5c72c29903813eJake Slack if (lrmit>=0 && _timeout!= lrmit) 28503928aee4356845252ac6b662d5c72c29903813eJake Slack { 28603928aee4356845252ac6b662d5c72c29903813eJake Slack _timeout=lrmit; 28703928aee4356845252ac6b662d5c72c29903813eJake Slack } 28803928aee4356845252ac6b662d5c72c29903813eJake Slack } 28903928aee4356845252ac6b662d5c72c29903813eJake Slack } 29003928aee4356845252ac6b662d5c72c29903813eJake Slack else 29103928aee4356845252ac6b662d5c72c29903813eJake Slack { 29203928aee4356845252ac6b662d5c72c29903813eJake Slack if (_timeout!=getMaxIdleTime()) 29303928aee4356845252ac6b662d5c72c29903813eJake Slack { 29403928aee4356845252ac6b662d5c72c29903813eJake Slack _timeout=getMaxIdleTime(); 29503928aee4356845252ac6b662d5c72c29903813eJake Slack } 29603928aee4356845252ac6b662d5c72c29903813eJake Slack } 29703928aee4356845252ac6b662d5c72c29903813eJake Slack 29803928aee4356845252ac6b662d5c72c29903813eJake Slack _connection = _connection.handle(); 29903928aee4356845252ac6b662d5c72c29903813eJake Slack 30003928aee4356845252ac6b662d5c72c29903813eJake Slack } 30103928aee4356845252ac6b662d5c72c29903813eJake Slack } 30203928aee4356845252ac6b662d5c72c29903813eJake Slack catch (EofException e) 30303928aee4356845252ac6b662d5c72c29903813eJake Slack { 30403928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("EOF", e); 30503928aee4356845252ac6b662d5c72c29903813eJake Slack try{BlockingChannelEndPoint.this.close();} 30603928aee4356845252ac6b662d5c72c29903813eJake Slack catch(IOException e2){LOG.ignore(e2);} 30703928aee4356845252ac6b662d5c72c29903813eJake Slack } 30803928aee4356845252ac6b662d5c72c29903813eJake Slack catch (HttpException e) 30903928aee4356845252ac6b662d5c72c29903813eJake Slack { 31003928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("BAD", e); 31103928aee4356845252ac6b662d5c72c29903813eJake Slack try{super.close();} 31203928aee4356845252ac6b662d5c72c29903813eJake Slack catch(IOException e2){LOG.ignore(e2);} 31303928aee4356845252ac6b662d5c72c29903813eJake Slack } 31403928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Throwable e) 31503928aee4356845252ac6b662d5c72c29903813eJake Slack { 31603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("handle failed",e); 31703928aee4356845252ac6b662d5c72c29903813eJake Slack try{super.close();} 31803928aee4356845252ac6b662d5c72c29903813eJake Slack catch(IOException e2){LOG.ignore(e2);} 31903928aee4356845252ac6b662d5c72c29903813eJake Slack } 32003928aee4356845252ac6b662d5c72c29903813eJake Slack finally 32103928aee4356845252ac6b662d5c72c29903813eJake Slack { 32203928aee4356845252ac6b662d5c72c29903813eJake Slack connectionClosed(_connection); 32303928aee4356845252ac6b662d5c72c29903813eJake Slack _endpoints.remove(this); 32403928aee4356845252ac6b662d5c72c29903813eJake Slack 32503928aee4356845252ac6b662d5c72c29903813eJake Slack // wait for client to close, but if not, close ourselves. 32603928aee4356845252ac6b662d5c72c29903813eJake Slack try 32703928aee4356845252ac6b662d5c72c29903813eJake Slack { 32803928aee4356845252ac6b662d5c72c29903813eJake Slack if (!_socket.isClosed()) 32903928aee4356845252ac6b662d5c72c29903813eJake Slack { 33003928aee4356845252ac6b662d5c72c29903813eJake Slack long timestamp=System.currentTimeMillis(); 33103928aee4356845252ac6b662d5c72c29903813eJake Slack int max_idle=getMaxIdleTime(); 33203928aee4356845252ac6b662d5c72c29903813eJake Slack 33303928aee4356845252ac6b662d5c72c29903813eJake Slack _socket.setSoTimeout(getMaxIdleTime()); 33403928aee4356845252ac6b662d5c72c29903813eJake Slack int c=0; 33503928aee4356845252ac6b662d5c72c29903813eJake Slack do 33603928aee4356845252ac6b662d5c72c29903813eJake Slack { 33703928aee4356845252ac6b662d5c72c29903813eJake Slack c = _socket.getInputStream().read(); 33803928aee4356845252ac6b662d5c72c29903813eJake Slack } 33903928aee4356845252ac6b662d5c72c29903813eJake Slack while (c>=0 && (System.currentTimeMillis()-timestamp)<max_idle); 34003928aee4356845252ac6b662d5c72c29903813eJake Slack if (!_socket.isClosed()) 34103928aee4356845252ac6b662d5c72c29903813eJake Slack _socket.close(); 34203928aee4356845252ac6b662d5c72c29903813eJake Slack } 34303928aee4356845252ac6b662d5c72c29903813eJake Slack } 34403928aee4356845252ac6b662d5c72c29903813eJake Slack catch(IOException e) 34503928aee4356845252ac6b662d5c72c29903813eJake Slack { 34603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.ignore(e); 34703928aee4356845252ac6b662d5c72c29903813eJake Slack } 34803928aee4356845252ac6b662d5c72c29903813eJake Slack } 34903928aee4356845252ac6b662d5c72c29903813eJake Slack } 35003928aee4356845252ac6b662d5c72c29903813eJake Slack 35103928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 35203928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 35303928aee4356845252ac6b662d5c72c29903813eJake Slack public String toString() 35403928aee4356845252ac6b662d5c72c29903813eJake Slack { 35503928aee4356845252ac6b662d5c72c29903813eJake Slack return String.format("BCEP@%x{l(%s)<->r(%s),open=%b,ishut=%b,oshut=%b}-{%s}", 35603928aee4356845252ac6b662d5c72c29903813eJake Slack hashCode(), 35703928aee4356845252ac6b662d5c72c29903813eJake Slack _socket.getRemoteSocketAddress(), 35803928aee4356845252ac6b662d5c72c29903813eJake Slack _socket.getLocalSocketAddress(), 35903928aee4356845252ac6b662d5c72c29903813eJake Slack isOpen(), 36003928aee4356845252ac6b662d5c72c29903813eJake Slack isInputShutdown(), 36103928aee4356845252ac6b662d5c72c29903813eJake Slack isOutputShutdown(), 36203928aee4356845252ac6b662d5c72c29903813eJake Slack _connection); 36303928aee4356845252ac6b662d5c72c29903813eJake Slack } 36403928aee4356845252ac6b662d5c72c29903813eJake Slack 36503928aee4356845252ac6b662d5c72c29903813eJake Slack } 36603928aee4356845252ac6b662d5c72c29903813eJake Slack} 367