Revert Server behaviour to what it was :
[nikiroo-utils.git] / src / be / nikiroo / utils / serial / Server.java
index e15680e5862d799291a732c52e7877b5fcad6c7a..934be33786e27b1bbe159e39afce42cdbc373845 100644 (file)
@@ -114,6 +114,8 @@ abstract public class Server implements Runnable {
 
        /**
         * Return the assigned port.
+        * 
+        * @return the assigned port
         */
        public int getPort() {
                return port;
@@ -123,25 +125,105 @@ abstract public class Server implements Runnable {
         * Start the server (listen on the network for new connections).
         * <p>
         * Can only be called once.
+        * <p>
+        * This call is asynchronous, and will just start a new {@link Thread} on
+        * itself (see {@link Server#run()}).
         */
        public void start() {
-               boolean ok = false;
+               new Thread(this).start();
+       }
+
+       /**
+        * Start the server (listen on the network for new connections).
+        * <p>
+        * Can only be called once.
+        * <p>
+        * You may call it via {@link Server#start()} for an asynchronous call, too.
+        */
+       @Override
+       public void run() {
+               ServerSocket ss = null;
+               boolean alreadyStarted = false;
                synchronized (lock) {
+                       ss = this.ss;
                        if (!started && ss != null) {
                                started = true;
-                               new Thread(this).start();
-                               ok = true;
+                       } else {
+                               alreadyStarted = started;
                        }
                }
 
-               if (ok) {
-                       tracer.trace(name + ": server started on port " + port);
-               } else if (ss == null) {
-                       tracer.error(name + ": cannot start server on port " + port
-                                       + ", it has already been used");
-               } else {
+               if (alreadyStarted) {
                        tracer.error(name + ": cannot start server on port " + port
                                        + ", it is already started");
+                       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);
                }
        }
 
@@ -184,18 +266,14 @@ abstract public class Server implements Runnable {
         *            or 0 for "no timeout"
         */
        private void stop(long timeout) {
+               tracer.trace(name + ": server stopping on port " + port);
                synchronized (lock) {
                        if (started && !exiting) {
                                exiting = true;
 
                                try {
-                                       new ConnectActionClient(createSocket(null, port, ssl)) {
-                                               @Override
-                                               public void action(Version serverVersion)
-                                                               throws Exception {
-                                               }
-                                       }.connect();
-
+                                       new ConnectActionClient(createSocket(null, port, ssl))
+                                                       .connect();
                                        long time = 0;
                                        while (ss != null && timeout > 0 && timeout > time) {
                                                Thread.sleep(10);
@@ -219,72 +297,6 @@ abstract public class Server implements Runnable {
                }
        }
 
-       @Override
-       public void run() {
-               try {
-                       tracer.trace(name + ": server starting on port " + port);
-                       while (started && !exiting) {
-                               count(1);
-                               Socket s = ss.accept();
-                               new ConnectActionServer(s) {
-                                       private Version clientVersion = new Version();
-
-                                       @Override
-                                       public void action(Version dummy) throws Exception {
-                                               try {
-                                                       for (Object data = flush(); true; data = flush()) {
-                                                               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
-                                               }
-                                       }
-
-                                       @Override
-                                       public void connect() {
-                                               try {
-                                                       super.connect();
-                                               } finally {
-                                                       count(-1);
-                                               }
-                                       }
-
-                                       @Override
-                                       protected void onClientVersionReceived(Version clientVersion) {
-                                               this.clientVersion = clientVersion;
-                                       }
-                               }.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);
-                       }
-
-                       ss = null;
-
-                       started = false;
-                       exiting = false;
-                       counter = 0;
-               }
-       }
-
        /**
         * This is the method that is called on each client request.
         * <p>