public void run ( ) { originalSecurityManager = System . getSecurityManager ( ) ; System . setSecurityManager ( new NGSecurityManager ( originalSecurityManager ) ) ; if ( ! ( System . in instanceof ThreadLocalInputStream ) ) { System . setIn ( new ThreadLocalInputStream ( in ) ) ; } if ( ! ( System . out instanceof ThreadLocalPrintStream ) ) { System . setOut ( new ThreadLocalPrintStream ( out ) ) ; } if ( ! ( System . err instanceof ThreadLocalPrintStream ) ) { System . setErr ( new ThreadLocalPrintStream ( err ) ) ; } try { if ( listeningAddress . isInetAddress ( ) ) { if ( listeningAddress . getInetAddress ( ) == null ) { serversocket = new ServerSocket ( listeningAddress . getInetPort ( ) ) ; } else { serversocket = new ServerSocket ( listeningAddress . getInetPort ( ) , 0 , listeningAddress . getInetAddress ( ) ) ; } } else { if ( Platform . isWindows ( ) ) { boolean requireStrictLength = true ; serversocket = new NGWin32NamedPipeServerSocket ( listeningAddress . getLocalAddress ( ) , requireStrictLength ) ; } else { serversocket = new NGUnixDomainServerSocket ( listeningAddress . getLocalAddress ( ) ) ; } } String portDescription ; if ( listeningAddress . isInetAddress ( ) && listeningAddress . getInetPort ( ) == 0 ) { // if the port is 0, it will be automatically determined. // add this little wait so the ServerSocket can fully // initialize and we can see what port it chose. int runningPort = getPort ( ) ; while ( runningPort == 0 ) { try { Thread . sleep ( 50 ) ; } catch ( Throwable toIgnore ) { } runningPort = getPort ( ) ; } portDescription = ", port " + runningPort ; } else { portDescription = "" ; } // at this moment server is capable to accept connections running . set ( true ) ; // Only after this point nailgun server is ready to accept connections on all platforms. // test_ng.py on *nix relies on reading this line from stdout to start connecting to server. out . println ( "NGServer " + NGConstants . VERSION + " started on " + listeningAddress . toString ( ) + portDescription + "." ) ; while ( ! shutdown . get ( ) ) { // this call blocks until a new connection is available, or socket is closed and // IOException is thrown Socket socket = serversocket . accept ( ) ; // get a session and run nail on it // the session is responsible to return itself to the pool // TBD: should we reconsider this? sessionPool . take ( ) . run ( socket ) ; } } catch ( IOException ex ) { // If shutdown is called while the accept() method is blocking, it wil throw IOException // Do not propagate it if we are in shutdown mode if ( ! shutdown . get ( ) ) { throw new RuntimeException ( ex ) ; } } // close all idle sessions and wait for all running sessions to complete try { sessionPool . shutdown ( ) ; } catch ( Throwable ex ) { // we are going to die anyways so let's just continue LOG . log ( Level . WARNING , "Exception shutting down Nailgun server" , ex ) ; } // restore system streams System . setIn ( in ) ; System . setOut ( out ) ; System . setErr ( err ) ; System . setSecurityManager ( originalSecurityManager ) ; running . set ( false ) ; }
Listens for new connections and launches NGSession threads to process them .