FileDocCategorySizeDatePackage
ASServerSocket.javaAPI DocGlassfish v2 API12034Fri May 04 22:35:52 BST 2007com.sun.enterprise.server.ss.provider

ASServerSocket

public final class ASServerSocket extends ServerSocket
Wrapper for the ServerSocket returned from ServerSocketChannel

Fields Summary
private static final Logger
logger
private ServerSocket
ss
private ASServerSocketChannel
sschan
private boolean
toBind
private LinkedList
socketCache
private final LinkedList
clientSocketLocalPorts
Constructors Summary
ASServerSocket(ServerSocket ss, ASServerSocketChannel sschan)


        
	      
        this.ss = ss;
        this.sschan = sschan;
    
Methods Summary
public synchronized java.net.Socketaccept()
Logic of accept method: When any appserver service do a serversocket.accept(), it will reach the following method. 1. Try to get a socket from its cache, for a client in same VM. 2. Get the first socket in the cache. 3. If there is nothing in the socket cache, do an actual accept This is the most common case. The first ever accept will do ss.accept() 4. If clientSocketLocalPorts empty (i.e there is no request waiting in the same VM) then do ASSocketService.waitOnAccept. waitOnAccept will block until server startup or until connection request from within the same VM. 5. There is a socket connection request waiting on the same VM. So we need to accept that request. Find for that socket.


        Socket s = getAlreadyAcceptedSocketInSameVM();


        if ( s != null) { // Comment 1.
           return s;
        } else {
           s = getFirstSocketFromCache(); // Comment 2.
        }


        if (s == null) {
            s = acceptSocket(); // Comment 3.
        }

        if ( logger.isLoggable(Level.FINE) ) {
	    logger.fine("In ASServerSocket.accept got connection, s.port="
                         +s.getPort()+" s.localPort="+s.getLocalPort());
        }

        if ( hasClientSocketLocalPorts() == false) { // Comment 4.
            ASSocketFacadeUtils.getASSocketService().waitOnAccept(s);
        }

        if (hasClientSocketLocalPorts()) { //Comment 5
            s = findSocketInSameVM(s);
        }

        return s;
    
private java.net.SocketacceptSocket()

        return  ss.accept();
    
public voidaddClientSocketLocalPort(int port)

        synchronized (clientSocketLocalPorts) {
            clientSocketLocalPorts.addLast(new Integer(port));
        }
    
public voidbind(java.net.SocketAddress s)

	// 0 for backlog results in default value being used
        this.bind(s, 0);
    
public voidbind(java.net.SocketAddress s, int backlog)


	int port = ((InetSocketAddress)s).getPort();

        if ( logger.isLoggable(Level.FINER) ) {
	     logger.log(Level.FINER, "In ASServerSocket.bind for port " + port, 
		   new Exception());
        }

        sschan.setPortNumber(port);

        if (!ASSocketFacadeUtils.getASSocketService().exists(port)) { 
            ss.bind(s, backlog);
	}
	else { // this port is managed by the ASSocketService
	    ServerSocket savedss = getServerSocket(port); 
	    if (savedss != null) {
		// replace the ServerSocketChannel and ServerSocket with the
		// ones created for this port at startup time.
		ss = savedss; 
		sschan.setServerSocketChannel(ss.getChannel()); 
	    }

	    int state = getPortState(port);
	    if (state != ASSelectorProvider.PORT_BOUND) {
		// This may cause an exception if there is a port conflict
                try {
		    ss.bind(s, backlog);
                } catch (IOException ie) {
                    throw ie;
                } catch (Throwable t) {
                    if (t.getCause() instanceof SocketException) {
                        throw (SocketException) t.getCause();
                    }
                    throw new BindException(t.getMessage() + ":" + port);
                }
	    } else if (state == ASSelectorProvider.PORT_BOUND) {
                // The real listener is up. No need for the old listener.
                ASSocketFacadeUtils.getASSocketService().
                                                 removeListeningSelector(port);
            }

	    // set the ServerSocket and update the state for this port
	    setServerSocket(ss, port);
	}
        if ( logger.isLoggable(Level.FINE) ) {
            logger.fine("In ASServerSocket.bind, bound at port " + ss.getLocalPort());
        }
    
public voidclose()

        ASSocketFacadeUtils.getASSocketService().close(getLocalPort(), ss, 
        (ServerSocketChannel) sschan.getActualChannel());
    
private java.net.SocketfindSocketInSameVM(java.net.Socket s)
If the clientSocketLocalPorts table contains the local port, of the socket, then return that. Otherwise loop until such socket is accepted.

        Socket result = s;
        while (true) {
            if ( ASSocketFacadeUtils.getASSocketService().isLocalClient(result) ) {
                Integer port = new Integer(result.getPort());
                synchronized (clientSocketLocalPorts) {
                    if (clientSocketLocalPorts.remove(port)) {
                        break;
                    }
                }
            } 

            LinkedList cache = getSocketCache();
            cache.addLast(result);
            result = acceptSocket();
        }
        return result;
    
private java.net.SocketgetAlreadyAcceptedSocketInSameVM()
1. If socket cache is null or empty return null. 2. If there is more than one socket in the cache and clientSocketLocalPorts is not empty then try to find the socket in the cache that has client request. Then return it.

        if (socketCache != null) {
            if (socketCache.size() > 0 && clientSocketLocalPorts.size() > 0) {
                Iterator it = socketCache.iterator();
                Socket result = null;
                while (it.hasNext()) {
                    result = (Socket) it.next();
                    if ( ASSocketFacadeUtils.getASSocketService().isLocalClient(result) ) {
                        Integer port = new Integer(result.getPort());
                        synchronized (clientSocketLocalPorts) {
                            if (clientSocketLocalPorts.remove(port)) {
                               it.remove();
                               return result; // Comment 2.
                            }
                        }
                    }
                }
            } 
        } 
        return null; // Comment 1.
    
public java.nio.channels.ServerSocketChannelgetChannel()

         return sschan;
    
private java.net.SocketgetFirstSocketFromCache()
1. return the first socket in the cache.

        if (socketCache != null && socketCache.size() > 0 ) {
            return (Socket) socketCache.removeFirst(); // Comment 3, 4
        } else {
            return null;
        }
    
public java.net.InetAddressgetInetAddress()

        return ss.getInetAddress();
    
public intgetLocalPort()

        return ss.getLocalPort();
    
public java.net.SocketAddressgetLocalSocketAddress()

        return ss.getLocalSocketAddress();
    
private intgetPortState(int port)

        ASSelectorProvider provider = 
		(ASSelectorProvider) SelectorProvider.provider();
        return provider.getPortState(port);
    
public synchronized intgetReceiveBufferSize()

        return ss.getReceiveBufferSize();
    
public booleangetReuseAddress()

        return ss.getReuseAddress();
    
private java.net.ServerSocketgetServerSocket(int port)

        ASSelectorProvider provider = 
        (ASSelectorProvider) SelectorProvider.provider();
        return provider.getServerSocket(port);
    
public synchronized intgetSoTimeout()

        return ss.getSoTimeout();
    
private java.util.LinkedListgetSocketCache()

        if (socketCache == null) {
            socketCache = new LinkedList();
        } 
        return socketCache;
    
public booleanhasClientSocketLocalPorts()

        return clientSocketLocalPorts.size() > 0;
    
public booleanisBound()

        return ss.isBound();
    
public booleanisClosed()

        return ss.isClosed();
    
public synchronized voidsetReceiveBufferSize(int i)

        if ( logger.isLoggable(Level.FINE) ) {
	    logger.fine("In ASServerSocket.setReceiveBufferSize = "+i);
        }
        ss.setReceiveBufferSize(i);
    
public voidsetReuseAddress(boolean b)

       if ( logger.isLoggable(Level.FINE) ) {
	    logger.fine("In ASServerSocket.setReuseAddress = "+b);
        }
        ss.setReuseAddress(b);
    
private voidsetServerSocket(java.net.ServerSocket ss, int port)

        ASSelectorProvider provider = 
        (ASSelectorProvider) SelectorProvider.provider();
        provider.setServerSocket(ss, port);
    
public synchronized voidsetSoTimeout(int i)

        if ( logger.isLoggable(Level.FINE) ) {
	    logger.fine("In ASServerSocket.setSoTimeout = "+i);
        }
        ss.setSoTimeout(i);
    
public java.lang.StringtoString()

        return ss.toString();