diff src/org/eclipse/jetty/io/nio/ChannelEndPoint.java @ 802:3428c60d7cfc

replace jetty jars with source
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 07 Sep 2016 21:15:48 -0600
parents
children 8e9db0bbf4f9
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/eclipse/jetty/io/nio/ChannelEndPoint.java	Wed Sep 07 21:15:48 2016 -0600
@@ -0,0 +1,509 @@
+//
+//  ========================================================================
+//  Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd.
+//  ------------------------------------------------------------------------
+//  All rights reserved. This program and the accompanying materials
+//  are made available under the terms of the Eclipse Public License v1.0
+//  and Apache License v2.0 which accompanies this distribution.
+//
+//      The Eclipse Public License is available at
+//      http://www.eclipse.org/legal/epl-v10.html
+//
+//      The Apache License v2.0 is available at
+//      http://www.opensource.org/licenses/apache2.0.php
+//
+//  You may elect to redistribute this code under either of these licenses.
+//  ========================================================================
+//
+
+package org.eclipse.jetty.io.nio;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.net.SocketException;
+import java.nio.ByteBuffer;
+import java.nio.channels.ByteChannel;
+import java.nio.channels.GatheringByteChannel;
+import java.nio.channels.SelectableChannel;
+import java.nio.channels.SocketChannel;
+
+import org.eclipse.jetty.io.Buffer;
+import org.eclipse.jetty.io.EndPoint;
+import org.eclipse.jetty.util.StringUtil;
+import org.eclipse.jetty.util.log.Log;
+import org.eclipse.jetty.util.log.Logger;
+
+/**
+ * Channel End Point.
+ * <p>Holds the channel and socket for an NIO endpoint.
+ *
+ */
+public class ChannelEndPoint implements EndPoint
+{
+    private static final Logger LOG = Log.getLogger(ChannelEndPoint.class);
+
+    protected final ByteChannel _channel;
+    protected final ByteBuffer[] _gather2=new ByteBuffer[2];
+    protected final Socket _socket;
+    protected final InetSocketAddress _local;
+    protected final InetSocketAddress _remote;
+    protected volatile int _maxIdleTime;
+    private volatile boolean _ishut;
+    private volatile boolean _oshut;
+
+    public ChannelEndPoint(ByteChannel channel) throws IOException
+    {
+        super();
+        this._channel = channel;
+        _socket=(channel instanceof SocketChannel)?((SocketChannel)channel).socket():null;
+        if (_socket!=null)
+        {
+            _local=(InetSocketAddress)_socket.getLocalSocketAddress();
+            _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
+            _maxIdleTime=_socket.getSoTimeout();
+        }
+        else
+        {
+            _local=_remote=null;
+        }
+    }
+
+    protected ChannelEndPoint(ByteChannel channel, int maxIdleTime) throws IOException
+    {
+        this._channel = channel;
+        _maxIdleTime=maxIdleTime;
+        _socket=(channel instanceof SocketChannel)?((SocketChannel)channel).socket():null;
+        if (_socket!=null)
+        {
+            _local=(InetSocketAddress)_socket.getLocalSocketAddress();
+            _remote=(InetSocketAddress)_socket.getRemoteSocketAddress();
+            _socket.setSoTimeout(_maxIdleTime);
+        }
+        else
+        {
+            _local=_remote=null;
+        }
+    }
+
+    public boolean isBlocking()
+    {
+        return  !(_channel instanceof SelectableChannel) || ((SelectableChannel)_channel).isBlocking();
+    }
+
+    public boolean blockReadable(long millisecs) throws IOException
+    {
+        return true;
+    }
+
+    public boolean blockWritable(long millisecs) throws IOException
+    {
+        return true;
+    }
+
+    /*
+     * @see org.eclipse.io.EndPoint#isOpen()
+     */
+    public boolean isOpen()
+    {
+        return _channel.isOpen();
+    }
+
+    /** Shutdown the channel Input.
+     * Cannot be overridden. To override, see {@link #shutdownInput()}
+     * @throws IOException
+     */
+    protected final void shutdownChannelInput() throws IOException
+    {
+        LOG.debug("ishut {}", this);
+        _ishut = true;
+        if (_channel.isOpen())
+        {
+            if (_socket != null)
+            {
+                try
+                {
+                    if (!_socket.isInputShutdown())
+                    {
+                        _socket.shutdownInput();
+                    }
+                }
+                catch (SocketException e)
+                {
+                    LOG.debug(e.toString());
+                    LOG.ignore(e);
+                }
+                finally
+                {
+                    if (_oshut)
+                    {
+                        close();
+                    }
+                }
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.io.EndPoint#close()
+     */
+    public void shutdownInput() throws IOException
+    {
+        shutdownChannelInput();
+    }
+
+    protected final void shutdownChannelOutput() throws IOException
+    {
+        LOG.debug("oshut {}",this);
+        _oshut = true;
+        if (_channel.isOpen())
+        {
+            if (_socket != null)
+            {
+                try
+                {
+                    if (!_socket.isOutputShutdown())
+                    {
+                        _socket.shutdownOutput();
+                    }
+                }
+                catch (SocketException e)
+                {
+                    LOG.debug(e.toString());
+                    LOG.ignore(e);
+                }
+                finally
+                {
+                    if (_ishut)
+                    {
+                        close();
+                    }
+                }
+            }
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.io.EndPoint#close()
+     */
+    public void shutdownOutput() throws IOException
+    {
+        shutdownChannelOutput();
+    }
+
+    public boolean isOutputShutdown()
+    {
+        return _oshut || !_channel.isOpen() || _socket != null && _socket.isOutputShutdown();
+    }
+
+    public boolean isInputShutdown()
+    {
+        return _ishut || !_channel.isOpen() || _socket != null && _socket.isInputShutdown();
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.io.EndPoint#close()
+     */
+    public void close() throws IOException
+    {
+        LOG.debug("close {}",this);
+        _channel.close();
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.io.EndPoint#fill(org.eclipse.io.Buffer)
+     */
+    public int fill(Buffer buffer) throws IOException
+    {
+        if (_ishut)
+            return -1;
+        Buffer buf = buffer.buffer();
+        int len=0;
+        if (buf instanceof NIOBuffer)
+        {
+            final NIOBuffer nbuf = (NIOBuffer)buf;
+            final ByteBuffer bbuf=nbuf.getByteBuffer();
+
+            //noinspection SynchronizationOnLocalVariableOrMethodParameter
+            try
+            {
+                synchronized(bbuf)
+                {
+                    try
+                    {
+                        bbuf.position(buffer.putIndex());
+                        len=_channel.read(bbuf);
+                    }
+                    finally
+                    {
+                        buffer.setPutIndex(bbuf.position());
+                        bbuf.position(0);
+                    }
+                }
+
+                if (len<0 && isOpen())
+                {
+                    if (!isInputShutdown())
+                        shutdownInput();
+                    if (isOutputShutdown())
+                        _channel.close();
+                }
+            }
+            catch (IOException x)
+            {
+                LOG.debug("Exception while filling", x);
+                try
+                {
+                    if (_channel.isOpen())
+                        _channel.close();
+                }
+                catch (Exception xx)
+                {
+                    LOG.ignore(xx);
+                }
+
+                if (len>0)
+                    throw x;
+                len=-1;
+            }
+        }
+        else
+        {
+            throw new IOException("Not Implemented");
+        }
+
+        return len;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.io.EndPoint#flush(org.eclipse.io.Buffer)
+     */
+    public int flush(Buffer buffer) throws IOException
+    {
+        Buffer buf = buffer.buffer();
+        int len=0;
+        if (buf instanceof NIOBuffer)
+        {
+            final NIOBuffer nbuf = (NIOBuffer)buf;
+            final ByteBuffer bbuf=nbuf.getByteBuffer().asReadOnlyBuffer();
+            try
+            {
+                bbuf.position(buffer.getIndex());
+                bbuf.limit(buffer.putIndex());
+                len=_channel.write(bbuf);
+            }
+            finally
+            {
+                if (len>0)
+                    buffer.skip(len);
+            }
+        }
+        else if (buf instanceof RandomAccessFileBuffer)
+        {
+            len = ((RandomAccessFileBuffer)buf).writeTo(_channel,buffer.getIndex(),buffer.length());
+            if (len>0)
+                buffer.skip(len);
+        }
+        else if (buffer.array()!=null)
+        {
+            ByteBuffer b = ByteBuffer.wrap(buffer.array(), buffer.getIndex(), buffer.length());
+            len=_channel.write(b);
+            if (len>0)
+                buffer.skip(len);
+        }
+        else
+        {
+            throw new IOException("Not Implemented");
+        }
+        return len;
+    }
+
+    /* (non-Javadoc)
+     * @see org.eclipse.io.EndPoint#flush(org.eclipse.io.Buffer, org.eclipse.io.Buffer, org.eclipse.io.Buffer)
+     */
+    public int flush(Buffer header, Buffer buffer, Buffer trailer) throws IOException
+    {
+        int length=0;
+
+        Buffer buf0 = header==null?null:header.buffer();
+        Buffer buf1 = buffer==null?null:buffer.buffer();
+
+        if (_channel instanceof GatheringByteChannel &&
+            header!=null && header.length()!=0 && buf0 instanceof NIOBuffer &&
+            buffer!=null && buffer.length()!=0 && buf1 instanceof NIOBuffer)
+        {
+            length = gatheringFlush(header,((NIOBuffer)buf0).getByteBuffer(),buffer,((NIOBuffer)buf1).getByteBuffer());
+        }
+        else
+        {
+            // flush header
+            if (header!=null && header.length()>0)
+                length=flush(header);
+
+            // flush buffer
+            if ((header==null || header.length()==0) &&
+                 buffer!=null && buffer.length()>0)
+                length+=flush(buffer);
+
+            // flush trailer
+            if ((header==null || header.length()==0) &&
+                (buffer==null || buffer.length()==0) &&
+                 trailer!=null && trailer.length()>0)
+                length+=flush(trailer);
+        }
+
+        return length;
+    }
+
+    protected int gatheringFlush(Buffer header, ByteBuffer bbuf0, Buffer buffer, ByteBuffer bbuf1) throws IOException
+    {
+        int length;
+
+        synchronized(this)
+        {
+            // Adjust position indexs of buf0 and buf1
+            bbuf0=bbuf0.asReadOnlyBuffer();
+            bbuf0.position(header.getIndex());
+            bbuf0.limit(header.putIndex());
+            bbuf1=bbuf1.asReadOnlyBuffer();
+            bbuf1.position(buffer.getIndex());
+            bbuf1.limit(buffer.putIndex());
+
+            _gather2[0]=bbuf0;
+            _gather2[1]=bbuf1;
+
+            // do the gathering write.
+            length=(int)((GatheringByteChannel)_channel).write(_gather2);
+
+            int hl=header.length();
+            if (length>hl)
+            {
+                header.clear();
+                buffer.skip(length-hl);
+            }
+            else if (length>0)
+            {
+                header.skip(length);
+            }
+        }
+        return length;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @return Returns the channel.
+     */
+    public ByteChannel getChannel()
+    {
+        return _channel;
+    }
+
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getLocalAddr()
+     */
+    public String getLocalAddr()
+    {
+        if (_socket==null)
+            return null;
+       if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress())
+           return StringUtil.ALL_INTERFACES;
+        return _local.getAddress().getHostAddress();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getLocalHost()
+     */
+    public String getLocalHost()
+    {
+        if (_socket==null)
+            return null;
+       if (_local==null || _local.getAddress()==null || _local.getAddress().isAnyLocalAddress())
+           return StringUtil.ALL_INTERFACES;
+        return _local.getAddress().getCanonicalHostName();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getLocalPort()
+     */
+    public int getLocalPort()
+    {
+        if (_socket==null)
+            return 0;
+        if (_local==null)
+            return -1;
+        return _local.getPort();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getRemoteAddr()
+     */
+    public String getRemoteAddr()
+    {
+        if (_socket==null)
+            return null;
+        if (_remote==null)
+            return null;
+        return _remote.getAddress().getHostAddress();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getRemoteHost()
+     */
+    public String getRemoteHost()
+    {
+        if (_socket==null)
+            return null;
+        if (_remote==null)
+            return null;
+        return _remote.getAddress().getCanonicalHostName();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getRemotePort()
+     */
+    public int getRemotePort()
+    {
+        if (_socket==null)
+            return 0;
+        return _remote==null?-1:_remote.getPort();
+    }
+
+    /* ------------------------------------------------------------ */
+    /*
+     * @see org.eclipse.io.EndPoint#getConnection()
+     */
+    public Object getTransport()
+    {
+        return _channel;
+    }
+
+    /* ------------------------------------------------------------ */
+    public void flush()
+        throws IOException
+    {
+    }
+
+    /* ------------------------------------------------------------ */
+    public int getMaxIdleTime()
+    {
+        return _maxIdleTime;
+    }
+
+    /* ------------------------------------------------------------ */
+    /**
+     * @see org.eclipse.jetty.io.bio.StreamEndPoint#setMaxIdleTime(int)
+     */
+    public void setMaxIdleTime(int timeMs) throws IOException
+    {
+        if (_socket!=null && timeMs!=_maxIdleTime)
+            _socket.setSoTimeout(timeMs>0?timeMs:0);
+        _maxIdleTime=timeMs;
+    }
+}