// Copyright (C) 2003-2009 by Object Mentor, Inc. All rights reserved.
// Released under the terms of the CPL Common Public License version 1.0.
package fitnesse.socketservice;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketException;
import java.util.LinkedList;
public class SocketService {
private ServerSocket serverSocket = null;
private Thread serviceThread = null;
private volatile boolean running = false;
private SocketServer server = null;
private LinkedList<Thread> threads = new LinkedList<Thread>();
private volatile boolean everRan=false;
public SocketService(int port, SocketServer server) throws IOException {
this.server = server;
serverSocket = new ServerSocket(port);
serviceThread = new Thread(
new Runnable() {
public void run() {
serviceThread();
}
}
);
serviceThread.start();
}
public void close() throws IOException {
waitForServiceThreadToStart();
running = false;
serverSocket.close();
try {
serviceThread.join();
waitForServerThreads();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void waitForServiceThreadToStart() {
if (everRan) return;
while (running == false) Thread.yield();
}
private void serviceThread() {
running = true;
everRan=true;
while (running) {
try {
Socket s = serverSocket.accept();
startServerThread(s);
}
catch (java.lang.OutOfMemoryError e) {
System.err.println("Can't create new thread. Out of Memory. Aborting");
e.printStackTrace();
System.exit(99);
}
catch (SocketException sox){
running=false;// do nothing
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
}
private void startServerThread(Socket s) {
Thread serverThread = new Thread(new ServerRunner(s));
synchronized (threads) {
threads.add(serverThread);
}
serverThread.start();
}
private void waitForServerThreads() throws InterruptedException {
while (threads.size() > 0) {
Thread t;
synchronized (threads) {
if (threads.size() < 1)
return;
t = threads.getFirst();
}
t.join();
}
}
private class ServerRunner implements Runnable {
private Socket socket;
ServerRunner(Socket s) {
socket = s;
}
public void run() {
try {
server.serve(socket);
synchronized (threads) {
threads.remove(Thread.currentThread());
}
}
catch (Exception e) {
}
}
}
}