FileDocCategorySizeDatePackage
ASSocketService.javaAPI DocGlassfish v2 API19862Mon Jul 30 03:33:08 BST 2007com.sun.enterprise.server.ss

ASSocketService

public final class ASSocketService extends Object implements com.sun.enterprise.server.ondemand.entry.EntryPoint
One each ASSocketService will be used for each port opened in domain.xml. It binds a port so that the client will not get exception when it tries to access the port.

Fields Summary
private static final Logger
logger
private static final com.sun.enterprise.util.i18n.StringManager
localStrings
private static final HashMap
managedPortsTable
private static com.sun.enterprise.server.PEMain
peMain
private static InetAddress
localHost
private static final String
SO_REUSEADDR_PROPERTY
private static final boolean
setReuseAddress
private ServerSocket
ss
private ServerSocketChannel
sschan
private Selector
sel
private static final int
TIMEOUT
private static boolean
triggered
static final int
NOTSTARTED
static final int
SERVICENOTIFIED
static final int
STARTING
static final int
STARTED
private int
state
private static final Object
lock
private final Object
acceptLock
private ASSocketServiceConfig
config
Constructors Summary
ASSocketService(ASSocketServiceConfig config)


      
        this.config = config;
	if ( localHost == null ) {
	    try {
		localHost = InetAddress.getLocalHost();
	    } catch ( Exception ex ) {}
	}
    
Methods Summary
void_initializeService()

         synchronized (managedPortsTable) {
	     // put the port in stable so that exists(port) returns true
             managedPortsTable.put(config.getPort(), this);
         }
	 // open channel and bind its ServerSocket
         sschan = ServerSocketChannel.open();
         ss = sschan.socket();
         if (setReuseAddress) {
             ss.setReuseAddress(true);
         }
         if (config.getBacklog() > 0) {
             ss.bind(config.getSocketAddress(), config.getBacklog());
         } else {
             ss.bind(config.getSocketAddress());
         }
    
void_reInitializeService()

        ASSelectorProvider provider = 
        (ASSelectorProvider) SelectorProvider.provider();
        provider.clear(config.getPort());
        synchronized (managedPortsTable) {
	    // put the port in stable so that exists(port) returns true
            managedPortsTable.remove(config.getPort());
        }

        try {
            if (this.sel != null) {
                this.sel.close();
            }
        } catch (Exception e) {
            logger.log(Level.FINEST, e.getMessage(), e);
        }

        int oldPort = config.getPort();
        config.init();
        /** In retrospect, the reInitialization is not that necessary.
            Commenting this out for now. Keeping this code within
            the comment so that it can be turned on later.

            Reinitialization will be required, when we automatically 
            stop containers that are idle.
        if (config.getPort() == oldPort) {
            _initializeService();
        }
        **/
    
void_socketServiceNotified(int port)

        if (state == NOTSTARTED) {
            // No one has started it so far.
            if (!ServerEntryHelper.isNotifiedByPortEntryContext(port)) {
                state = SERVICENOTIFIED;
            }
        }
    
void_waitForServiceStartUp(java.net.Socket s)

	if ( entryBeingProcessed() ) {
	    int localPort = s.getLocalPort();

	    // If client is in this JVM, dont wait
	    synchronized ( acceptLock ) {
	        while ( entryBeingProcessed() && 
                        ! ASSocketService.hasClientSocketLocalPorts(s) ) {
                    if ( logger.isLoggable(Level.FINE) ) {
		        logger.fine("In ASSocketService.waitForServiceStartUp for localport " + localPort);
                    }
		    try {
			acceptLock.wait();
		    } catch ( Exception ex ) {}
	        }
	    }
	} 

    
void_waitOnClientConnection()

        if (entryBeingProcessed()) {
            synchronized (acceptLock) {
                try {
                    while (entryBeingProcessed()) {
                        acceptLock.wait();
                    }
                } catch (InterruptedException ie) {
                }
            }
        }
    
static voidclientSocketConnected(int port, int localPort)

        boolean toAdd = true;
	if ( peMain.isStartingUp() ) {
            if ( logger.isLoggable(Level.FINE) ) { 
	        logger.fine("In ASSocketService.clientSocketConnected, adding port " 
			+ localPort);
            }

	    synchronized ( peMain ) {
                putClientSocketLocalPort(port, localPort);
                toAdd = false;
		peMain.notifyAll();
	    }
	}

        ASSocketService service = ASSocketService.get(port); 
        if (service != null && service.entryBeingProcessed()) {
	    synchronized ( service.acceptLock ) {
                if (toAdd) {
                    putClientSocketLocalPort(port, localPort);
                }
	        service.acceptLock.notifyAll();
	   }
        }

    
static booleanclose(int port, java.net.ServerSocket sock, java.nio.channels.ServerSocketChannel channel)


        ASSocketService savedSS = null;
        if (port > 0) {
            savedSS = ASSocketService.get(port);
            if (savedSS != null) { //If managed by socket service
                if (savedSS.entryBeingProcessed()) {
                    // Return and dont close
                    ASSelectorProvider pr = (ASSelectorProvider)
                    SelectorProvider.provider();
                    pr.setPortState(port, ASSelectorProvider.PORT_BOUND);
                    return false;
                }
            } 
        }

        boolean closed = false;
        try {
            if (channel != null) {
                if (channel.isOpen()) {
                    closed = true;
                    channel.close();
                }
            }
            if (sock != null) {
                if (sock.isClosed() == false) {
                    closed = true;
                    sock.close();
                }
            }
        } finally {
            if (savedSS != null && closed) {
                ASSocketService.reInitializeService(port);
            }
        }

        return true;
        
    
java.nio.channels.SelectorcreateListeningSelector()

        try {
            sschan.configureBlocking(false);
            this.sel = Selector.open();
            sschan.register(sel, SelectionKey.OP_ACCEPT);
        } catch (Exception e) {
            logger.log(Level.SEVERE, e.getMessage(), e);
        }
        return this.sel;
    
booleanentryBeingProcessed()

        return state != STARTED;
    
static booleanexists(int port)

        return managedPortsTable.containsKey(port);
    
public voidgenerateEntryContext(java.lang.Object context)

        if ( logger.isLoggable(Level.FINE) ) {
	     logger.fine("In ASSocketService.generateEntryContext for context " + context);
        }
        ServerEntryHelper.generatePortEntryContext((Integer) context);
    
static com.sun.enterprise.server.ss.ASSocketServiceget(int port)

        return managedPortsTable.get(port);
    
static java.net.ServerSocketgetServerSocket(int port)

        ASSocketService a = managedPortsTable.get(port);
        return a.ss;
    
static java.nio.channels.ServerSocketChannelgetServerSocketChannel(int port)

        ASSocketService a = managedPortsTable.get(port);
        return a.sschan;
    
static booleanhasClientSocketLocalPorts(java.net.Socket s)

        ASServerSocket ss = (ASServerSocket) getServerSocket(s.getLocalPort());
        return ss.hasClientSocketLocalPorts();
    
static voidinitialize()

	if ( peMain == null ) {
	    peMain = com.sun.enterprise.server.PEMain.getInstance();
	}
    
static booleanisLocalClient(java.net.Socket s)

        return isLocalClient(s.getInetAddress());
    
static booleanisLocalClient(java.net.InetAddress remoteAddr)

	    // Check if s is connected to a remote client (on a different machine)
	    return   (  remoteAddr.equals(localHost)
          	     || remoteAddr.isSiteLocalAddress() 
		     || remoteAddr.isLinkLocalAddress()
		     || remoteAddr.isLoopbackAddress()
		     || remoteAddr.isAnyLocalAddress());
    
static booleanisServerStartingUp()

        return peMain.isStartingUp();
    
static booleanisServerStartingUp(int port)

        if (isServerStartingUp() == true) {
            return true;
        }
        if (port > 0 ) {
            ASSocketService savedSS = ASSocketService.get(port);
            if (savedSS != null) {
                return savedSS.entryBeingProcessed();
            }
        }
        return false;
    
public static java.nio.channels.SelectionKeykeyFor(java.nio.channels.SelectableChannel channel, java.nio.channels.Selector sel)

        return channel.keyFor(((ASSelector) sel).getSelector());
    
static voidputClientSocketLocalPort(int serverPort, int localPort)

        if (exists(serverPort)) {
            ASServerSocket ss = (ASServerSocket) getServerSocket(serverPort);
            ss.addClientSocketLocalPort(localPort);
        } 
    
static voidreInitializeService(int port)

        ASSocketService savedSS = ASSocketService.get(port);
        if (savedSS != null) {
            savedSS._reInitializeService();
        }
    
static voidremoveListeningSelector(int port)

        try {
            ASSocketService savedSS = get(port);
            if (savedSS.sel != null) {
                savedSS.sel.close();
                savedSS.sschan.configureBlocking(true);
            }
        } catch (Exception e) {
            logger.log(Level.SEVERE, e.getMessage(), e);
        }
    
public static booleansocketServiceNotified(int port)


        ASSocketService ss = ASSocketService.get(port);
        if (ss != null) {
            InvocationManager im = Switch.getSwitch().getInvocationManager();
            //System.out.println("Startup invocation :" + im.isStartupInvocation());
            ss._socketServiceNotified(port);
            return im.isStartupInvocation();
        } else {
            return true;
        }
    
voidstart()

        try {
            config.init();
            _initializeService();
            if (config.getStartSelector() == true) {
                Selector select = createListeningSelector();
                (new EntryPointThread(select)).start();
            } else {
                // Socket service doesnt need to handle the
                // lifecycle.
                this.state = STARTED;
            }

            if ( logger.isLoggable(Level.FINE) ) {
                logger.fine("ASSocketService Successfully started for " + config);
            }
        } catch(IOException ie){
            String i18nMsg = localStrings.getString(
                "socketservice.port_conflict", new Object[]{String.valueOf(config.getPort())});
            throw new PortConflictException(config.getPort(),i18nMsg, ie);
        }
    
public static voidtriggerServerExit()

        synchronized (lock) {
            triggered = true;
            lock.notifyAll();
        }
    
public static voidwaitForClientNotification()

        synchronized (lock) {
            if (triggered == false) {
                try {
                    lock.wait(TIMEOUT);
                } catch (Exception e ) {
                    e.printStackTrace();
                }
            }
        }
    
static voidwaitForServiceStartUp(java.net.Socket s)

        ASSocketService savedService = get(s.getLocalPort());
        if ( savedService != null ) {
            savedService._waitForServiceStartUp(s);
        }
    
static voidwaitOnAccept(java.nio.channels.SocketChannel sc)

        // Redundant peMain.isStartingUp() is required since sc.socket() 
        // has to pass thru a synchronization.
	if ( peMain.isStartingUp() ) { 
            waitOnAccept(sc.socket());
        } else {
            waitForServiceStartUp(sc.socket());
        }

    
static voidwaitOnAccept(java.net.Socket s)

	if ( peMain.isStartingUp() ) {
	    int localPort = s.getLocalPort();
	    if ( !exists(localPort) ) { // Check if port is managed
		return;
	    }

	    // If client is in this JVM, dont wait
	    synchronized ( peMain ) {
	        while ( peMain.isStartingUp() && ! hasClientSocketLocalPorts(s) ) {
                    if ( logger.isLoggable(Level.FINE) ) {
		        logger.fine("In ASSocketService.waitOnAccept for localport " + localPort);
                    }
		    try {
			peMain.wait();
		    } catch ( Exception ex ) {}
	        }
	    }
	} 

        waitForServiceStartUp(s);
    
public static voidwaitOnClientConnection(int port)
If a client connects from within appserver and that triggers the service startup, that client should wait until service startup completes before being accepted by server. This method should be called, if and only if the connection is first ever connection to the server.

param
s A connected socket from client.

        ASSocketService ss = ASSocketService.get(port);
        if (ss != null) {
            ss._waitOnClientConnection();
        }