@Override
 public void run() {
   running = true;
   while (running) {
     try {
       final Socket s = socket.accept();
       if (stop.exists()) {
         if (!stop.delete()) log.write(Util.info(FILE_NOT_DELETED_X, stop));
         quit();
       } else {
         // drop inactive connections
         final long ka = context.mprop.num(MainProp.KEEPALIVE) * 1000L;
         if (ka > 0) {
           final long ms = System.currentTimeMillis();
           for (final ClientListener cs : context.sessions) {
             if (ms - cs.last > ka) cs.quit();
           }
         }
         new ClientListener(s, context, log, this).start();
       }
     } catch (final IOException ex) {
       // socket was closed..
       break;
     }
   }
 }
  @Override
  protected void quit() throws IOException {
    if (!running) return;
    running = false;
    for (final ClientListener cs : context.sessions) cs.quit();
    super.quit();
    context.close();

    try {
      // close interactive input if server was stopped by another process
      if (console) System.in.close();
      esocket.close();
      socket.close();
    } catch (final IOException ex) {
      log.write(ex.getMessage());
      Util.stack(ex);
    }
    console = false;
  }
  /**
   * Constructor.
   *
   * @param ctx database context
   * @param args command-line arguments
   * @throws IOException I/O exception
   */
  public BaseXServer(final Context ctx, final String... args) throws IOException {

    super(args, ctx);
    final MainProp mprop = context.mprop;
    final int port = mprop.num(MainProp.SERVERPORT);
    final int eport = mprop.num(MainProp.EVENTPORT);
    // check if ports are distinct
    if (port == eport) throw new BaseXException(PORT_TWICE_X, port);

    final String host = mprop.get(MainProp.SERVERHOST);
    final InetAddress addr = host.isEmpty() ? null : InetAddress.getByName(host);

    if (service) {
      start(port, args);
      Util.outln(SRV_STARTED);
      Performance.sleep(1000);
      return;
    }

    if (stopped) {
      stop(port, eport);
      Util.outln(SRV_STOPPED);
      Performance.sleep(1000);
      return;
    }

    try {
      // execute command-line arguments
      for (final String c : commands) execute(c);

      log = new Log(context, quiet);
      log.write(SRV_STARTED);

      socket = new ServerSocket();
      socket.setReuseAddress(true);
      socket.bind(new InetSocketAddress(addr, port));
      esocket = new ServerSocket();
      esocket.setReuseAddress(true);
      esocket.bind(new InetSocketAddress(addr, eport));
      stop = stopFile(port);

      // show info when server is aborted
      Runtime.getRuntime()
          .addShutdownHook(
              new Thread() {
                @Override
                public void run() {
                  log.write(SRV_STOPPED);
                  log.close();
                  Util.outln(SRV_STOPPED);
                }
              });

      new Thread(this).start();
      while (!running) Performance.sleep(100);

      Util.outln(CONSOLE + (console ? TRY_MORE_X : SRV_STARTED), SERVERMODE);

      if (console) {
        console();
        quit();
      }
    } catch (final IOException ex) {
      if (log != null) log.write(ex.getMessage());
      throw ex;
    }
  }