altosui: Make AltosSerial.flush_input keep reading while non-empty
[fw/altos] / ao-tools / altosui / AltosSerial.java
index 6787e0c82de78026566159eda85a1c51e513c770..8a6ad05e823cfac824121a8afc08ca6e804f18c2 100644 (file)
@@ -23,9 +23,8 @@ package altosui;
 
 import java.lang.*;
 import java.io.*;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.LinkedList;
-import java.util.Iterator;
+import java.util.concurrent.*;
+import java.util.*;
 
 import libaltosJNI.*;
 
@@ -37,6 +36,9 @@ import libaltosJNI.*;
 
 public class AltosSerial implements Runnable {
 
+       static List<String> devices_opened = Collections.synchronizedList(new LinkedList<String>());
+
+       AltosDevice device;
        SWIGTYPE_p_altos_file altos;
        LinkedList<LinkedBlockingQueue<AltosLine>> monitors;
        LinkedBlockingQueue<AltosLine> reply_queue;
@@ -112,16 +114,20 @@ public class AltosSerial implements Runnable {
 
        public void flush_input() {
                flush_output();
-               try {
-                       Thread.sleep(200);
-               } catch (InterruptedException ie) {
-               }
-               synchronized(this) {
-                       if (!"VERSION".startsWith(line) &&
-                           !line.startsWith("VERSION"))
-                               line = "";
-                       reply_queue.clear();
-               }
+               boolean got_some;
+               do {
+                       try {
+                               Thread.sleep(100);
+                       } catch (InterruptedException ie) {
+                       }
+                       got_some = !reply_queue.isEmpty();
+                       synchronized(this) {
+                               if (!"VERSION".startsWith(line) &&
+                                   !line.startsWith("VERSION"))
+                                       line = "";
+                               reply_queue.clear();
+                       }
+               } while (got_some);
        }
 
        public String get_reply() throws InterruptedException {
@@ -130,6 +136,14 @@ public class AltosSerial implements Runnable {
                return line.line;
        }
 
+       public String get_reply(int timeout) throws InterruptedException {
+               flush_output();
+               AltosLine line = reply_queue.poll(timeout, TimeUnit.MILLISECONDS);
+               if (line == null)
+                       return null;
+               return line.line;
+       }
+
        public void add_monitor(LinkedBlockingQueue<AltosLine> q) {
                set_monitor(true);
                monitors.add(q);
@@ -141,10 +155,6 @@ public class AltosSerial implements Runnable {
                        set_monitor(false);
        }
 
-       public boolean opened() {
-               return altos != null;
-       }
-
        public void close() {
                if (altos != null) {
                        libaltos.altos_close(altos);
@@ -161,6 +171,9 @@ public class AltosSerial implements Runnable {
                        libaltos.altos_free(altos);
                        altos = null;
                }
+               synchronized (devices_opened) {
+                       devices_opened.remove(device.getPath());
+               }
        }
 
        public void putc(char c) {
@@ -178,11 +191,15 @@ public class AltosSerial implements Runnable {
                print(String.format(format, arguments));
        }
 
-       public void open(altos_device device) throws FileNotFoundException {
-               close();
+       private void open() throws FileNotFoundException, AltosSerialInUseException {
+               synchronized (devices_opened) {
+                       if (devices_opened.contains(device.getPath()))
+                               throw new AltosSerialInUseException(device);
+                       devices_opened.add(device.getPath());
+               }
                altos = libaltos.altos_open(device);
                if (altos == null)
-                       throw new FileNotFoundException(device.getPath());
+                       throw new FileNotFoundException(device.toShortString());
                input_thread = new Thread(this);
                input_thread.start();
                print("~\nE 0\n");
@@ -220,12 +237,12 @@ public class AltosSerial implements Runnable {
                }
        }
 
-       public AltosSerial() {
-               altos = null;
-               input_thread = null;
+       public AltosSerial(AltosDevice in_device) throws FileNotFoundException, AltosSerialInUseException {
+               device = in_device;
                line = "";
                monitor_mode = false;
                monitors = new LinkedList<LinkedBlockingQueue<AltosLine>> ();
                reply_queue = new LinkedBlockingQueue<AltosLine> ();
+               open();
        }
 }