+ return;
+ }
+
+ if (ss == null) {
+ tracer.error(name + ": cannot start server on port " + port
+ + ", it has already been used");
+ return;
+ }
+
+ try {
+ tracer.trace(name + ": server starting on port " + port);
+
+ while (started && !exiting) {
+ count(1);
+ Socket s = ss.accept();
+ new ConnectActionServer(s) {
+ @Override
+ public void action(Version clientVersion) throws Exception {
+ try {
+ for (Object data = rec(); true; data = rec()) {
+ Object rep = null;
+ try {
+ rep = onRequest(this, clientVersion, data);
+ } catch (Exception e) {
+ onError(e);
+ }
+ send(rep);
+ }
+ } catch (NullPointerException e) {
+ // Client has no data any more, we quit
+ tracer.trace(name
+ + ": client has data no more, stopping connection");
+ }
+ }
+
+ @Override
+ public void connect() {
+ try {
+ super.connect();
+ } finally {
+ count(-1);
+ }
+ }
+ }.connectAsync();
+ }
+
+ // Will be covered by @link{Server#stop(long)} for timeouts
+ while (counter > 0) {
+ Thread.sleep(10);
+ }
+ } catch (Exception e) {
+ if (counter > 0) {
+ onError(e);
+ }
+ } finally {
+ try {
+ ss.close();
+ } catch (Exception e) {
+ onError(e);
+ }
+
+ this.ss = null;
+
+ started = false;
+ exiting = false;
+ counter = 0;
+
+ tracer.trace(name + ": client terminated on port " + port);