in nailgun-server/src/main/java/com/facebook/nailgun/NGServer.java [316:415]
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);
}