import javax.imageio.*; import java.awt.image.*; import java.awt.*; import java.security.NoSuchAlgorithmException; import java.security.MessageDigest; import java.lang.reflect.*; import java.net.*; import java.io.*; import javax.swing.*; import java.util.regex.*; import java.util.List; import java.util.zip.*; import java.util.*; class CircularFifoBuffer { int capacity; ArrayDeque storage; public CircularFifoBuffer(int capacity) { this.capacity = capacity; storage = new ArrayDeque(capacity); } /** * Adds the given element to the buffer. If the buffer is full, the least recently added element is discarded so * that a new element can be inserted. */ public void add(E e) { if (isFull()) { remove(); } storage.addLast(e); } /** * Removes and returns the least recently inserted element from this buffer. */ public E remove() { return storage.removeFirst(); } /** * Returns true iff the buffers remaining capacity is 0. */ public boolean isFull() { return storage.size() == capacity; } /** * Returns true iff the buffers size is 0. */ public boolean isEmpty() { return storage.isEmpty(); } /** * Returns the number of elements in the buffer. */ public int size() { return storage.size(); } public Object[] toArray() { return storage.toArray(); } public T[] toArray(T[] a) { return storage.toArray(a); } public ArrayDeque getBackingStore() { return storage; } } // CircularFifoBuffer /** this class is fully thread-safe */ class Flag { private boolean up; /** returns true if flag was down before */ public synchronized boolean raise() { return doRaise(); } private synchronized boolean doRaise() { if (!up) { up = true; notifyAll(); return true; } else return false; } public synchronized void waitUntilUp() { if (!up) { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } public synchronized boolean isUp() { return up; } public String toString() { return isUp() ? "up" : "down"; } // currently does a semi-active wait with latency = 50 ms public void waitForThisOr(Flag otherFlag) { try { while (!isUp() && !otherFlag.isUp()) Thread.sleep(50); } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} } // Flag public class main { static int port = 1234; static Flag killFlag = new Flag(); public static void main(String[] args) throws Exception { installKillSwitch(); print("Hello world. Sleeping. Port=" + port); killFlag.waitUntilUp(); } static void installKillSwitch() { try { final ServerSocket serverSocket = new ServerSocket(1234); //serverSocket.setSoTimeout(1000); Thread _t = new Thread() { public void run() { try { // todo: higher priority while (true) { try { final Socket s = serverSocket.accept(); print("connect"); Thread _t = new Thread() { public void run() { try { InputStream in = s.getInputStream(); CircularFifoBuffer b = new CircularFifoBuffer(4); while (true) { int i = in.read(); if (i < 0) break; print(i); b.add((char) i); String s = getLast(b, 4); //print("> " + s); if ("kill".equals(s)) killMe(); } print("disconnect"); } catch (Exception _e) { throw _e instanceof RuntimeException ? (RuntimeException) _e : new RuntimeException(_e); } } }; _t.start(); } catch (SocketTimeoutException e) { } } } catch (Exception _e) { throw _e instanceof RuntimeException ? (RuntimeException) _e : new RuntimeException(_e); } } }; _t.setDaemon(true); _t.start(); } catch (Throwable __e) { throw __e instanceof RuntimeException ? (RuntimeException) __e : new RuntimeException(__e); }} static void killMe() { print("killing"); // keepWakingUp(); // see sleep() above. Does this make sense? System.exit(0); // This works. // killFlag.raise(); // And this is a very safe way to do it too. } static String getLast(CircularFifoBuffer b, int n) { n = Math.min(n, b.size()); StringBuilder buf = new StringBuilder(); Iterator it = b.getBackingStore().descendingIterator(); for (int i = 0; i < n; i++) buf.append(it.next()); return buf.reverse().toString(); } static void print() { System.out.println(); } static void print(Object o) { System.out.println(o); } static void print(long i) { System.out.println(i); } }