diff src/com/five_ten_sg/connectbot/service/TerminalMonitor.java @ 397:2f2b5a244a4d

add queue to buffer monitor socket writes to prevent blocking on socket output stream write
author Carl Byington <carl@five-ten-sg.com>
date Wed, 15 Oct 2014 17:55:59 -0700
parents 071eccdff8ea
children 2a416391ffc3
line wrap: on
line diff
--- a/src/com/five_ten_sg/connectbot/service/TerminalMonitor.java	Fri Sep 19 15:27:51 2014 -0700
+++ b/src/com/five_ten_sg/connectbot/service/TerminalMonitor.java	Wed Oct 15 17:55:59 2014 -0700
@@ -68,9 +68,52 @@
     private InputStream         monitor_in     = null;
     private OutputStream        monitor_out    = null;
     private MyReader            monitor_reader = null;
-    private BlockingQueue<char[]> pending_commands = new ArrayBlockingQueue<char[]>(100);
+    private MyWriter            monitor_writer = null;
+    private BlockingQueue<char[]> pending_commands = new ArrayBlockingQueue<char[]>(10000);
     private MyServiceConnection monitor_connection = new MyServiceConnection();
 
+    class MyWriter extends Thread {
+        private OutputStream monitor_out;
+        private boolean is_closing = false;
+
+        public MyWriter(OutputStream monitor_out) {
+            this.monitor_out = monitor_out;
+        }
+
+        public void closing() {
+            is_closing = true;
+            this.interrupt();
+        }
+
+        public void run() {
+            char [] c;
+            try {
+                while (!is_closing) {
+                    c = pending_commands.take();
+                    c[0] = (char)(c.length - 1);    // number of chars following
+                    c[1] = cmd;
+                    //Log.i(TAG, String.format("sending %d command", (int)cmd));
+                    monitor_out.write(charsToBytes(c));
+                }
+            }
+            catch (InterruptedException e) {
+                if (!is_closing) Log.e(TAG, "exception in monitorWrite()", e);
+            }
+            catch (IOException e) {
+                Log.i(TAG, "exception in monitorWrite(), monitor died or closed the socket", e);
+            }
+
+            try {
+                monitor_out.close();
+            }
+            catch (IOException ee) {
+                Log.e(TAG, "exception in monitorWrite() closing output stream", ee);
+            }
+            monitor_out = null;
+        }
+    }
+
+
     class MyReader extends Thread {
         private InputStream monitor_in;
         private byte[] b;
@@ -180,17 +223,12 @@
                 Log.i(TAG, "connected to monitor socket, send init " + init);
                 monitor_reader = new MyReader(monitor_in);
                 monitor_reader.start();
+                monitor_writer = new MyWriter(monitor_out);
+                monitor_writer.start();
+
                 String x = "  " + init;
                 monitorWrite(MONITOR_CMD_INIT, x.toCharArray());
-                char [] c;
 
-                while (true) {
-                    c = pending_commands.poll();
-
-                    if (c == null) break;
-
-                    monitorWrite(c[1], c);
-                }
             }
             catch (IOException e) {
                 Log.e(TAG, "exception in onServiceConnected()", e);
@@ -259,7 +297,7 @@
 
     public void Disconnect() {
         if (monitor_reader != null) monitor_reader.closing();
-
+        if (monitor_writer != null) monitor_writer.closing();
         try {
             if (monitor_out    != null) monitor_out.close();
 
@@ -311,34 +349,9 @@
     }
 
 
-    public synchronized void monitorWrite(char cmd, char[] c) {
-        try {
-            if (monitor_out != null) {
-                c[0] = (char)(c.length - 1);    // number of chars following
-                c[1] = cmd;
-                //Log.i(TAG, String.format("sending %d command", (int)cmd));
-                monitor_out.write(charsToBytes(c));
-            }
-            else {
-                c[1] = cmd;
-                pending_commands.put(c);
-            }
-        }
-        catch (InterruptedException e) {
-            Log.e(TAG, "exception in monitorWrite()", e);
-        }
-        catch (IOException e) {
-            Log.i(TAG, "exception in monitorWrite(), monitor died or closed the socket", e);
-
-            try {
-                monitor_out.close();
-            }
-            catch (IOException ee) {
-                Log.e(TAG, "exception in monitorWrite() closing output stream", ee);
-            }
-
-            monitor_out = null;
-        }
+    public void monitorWrite(char cmd, char[] c) {
+        c[1] = cmd;
+        pending_commands.put(c);
     };
 
     public void resetWatch() {