!747
!721 // thread {

!include #1000774 // CircularFifoBuffer
!include #1000782 // Flag

m {
  static int port = 1234;
  static new Flag killFlag;

  p {
    installKillSwitch();
    print("Hello world. Sleeping. Port=" + port);
    killFlag.waitUntilUp();
  }

  static void installKillSwitch() ctex {
    final ServerSocket serverSocket = new ServerSocket(1234);
    //serverSocket.setSoTimeout(1000);
    
    daemon { // todo: higher priority
      while (true) {
        try {
          final Socket s = serverSocket.accept();
          print("connect");
          thread {
            InputStream in = s.getInputStream();
            CircularFifoBuffer<Character> b = new CircularFifoBuffer<Character>(4);
            while (true) {
              int i = in.read();
              if (i < 0) break;
              print(i);
              b.add((char) i);
              S s = getLast(b, 4);
              //print("> " + s);
              if (s == "kill")
                killMe();
            }
            print("disconnect");
          }
        } catch (SocketTimeoutException 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 S getLast(CircularFifoBuffer<Character> b, int n) {
    n = Math.min(n, b.size());
    new StringBuilder buf;
    Iterator<Character> it = b.getBackingStore().descendingIterator();
    for (int i = 0; i < n; i++)
      buf.append(it.next());
    return buf.reverse().toString();
  }
}