package net.sourceforge.pain.network.guitool;
import net.sourceforge.pain.util.*;
import java.io.*;
import java.net.*;
import java.util.*;
public final class GuiToolConnection implements Runnable {
private GuiToolServer server;
private final ObjectOutputStream os;
private final ObjectInputStream is;
private boolean forcedClose;
private boolean lostLink;
public Object guiAdminId = null;
public final LinkedList inputEvents = new LinkedList();
private final LinkedList outputEvents = new LinkedList();
Socket socket;
long sessionStartTime;
private final Object sendMonitor = new Object();
private Flusher flusher;
public GuiToolConnection(GuiToolServer server, Socket socket) throws IOException {
this.server = server;
this.socket = socket;
os = new ObjectOutputStream(socket.getOutputStream());
is = new ObjectInputStream(socket.getInputStream());
sessionStartTime = System.currentTimeMillis();
}
public void run() {
forcedClose = false;
flusher = new Flusher();
flusher.start();
try {
do {
try {
GTNetPacket inPacket = (GTNetPacket) is.readObject();
Log.debug("GTC: new event:" + inPacket.eventClassName);
inputEvents.add(inPacket);
} catch (InterruptedIOException e) {
break;
} catch (IOException e) {
if (!forcedClose) {
Log.error(e.getMessage(), e);
lostLink = true;
}
break;
} catch (Exception e) {
Log.error(e.getMessage(), e);
}
} while (!forcedClose && !lostLink);
} catch (Exception e) {
Log.error(e);
} finally {
flusher.die();
server.onClose(this);
try {
socket.close();
} catch (Exception ignored) {
}
}
}
public void forceClose() {
Log.debug("GTC:force close!");
forcedClose = true;
}
public void send(GTNetPacket packet) {
synchronized (sendMonitor) {
outputEvents.add(packet);
sendMonitor.notify();
}
}
private final class Flusher extends Thread {
private boolean isAlive = true;
public Flusher() {
setDaemon(true);
}
public void run() {
while (isAlive) {
if (outputEvents.isEmpty()) {
synchronized (sendMonitor) {
try {
sendMonitor.wait(50);
} catch (InterruptedException e) {
Log.error(e);
}
}
continue;
}
// ok we really have somethong to send
while (!outputEvents.isEmpty()) {
GTNetPacket packet;
synchronized (sendMonitor) {
packet = (GTNetPacket) outputEvents.removeFirst();
}
try {
os.writeObject(packet);
} catch (IOException e) {
Log.error(e); // do nothing, main thread will catch IO by itself
}
}
Log.debug("GTC: flushing");
try {
os.flush();
} catch (IOException e) {
Log.error(e); // do nothing, main thread will catch IO by itself
}
}
}
public void die() {
isAlive = false;
synchronized (sendMonitor) {
sendMonitor.notify();
}
}
}
}