comparison 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
comparison
equal deleted inserted replaced
396:1f625669d89d 397:2f2b5a244a4d
66 private IBinder bound = null; 66 private IBinder bound = null;
67 private Socket monitor_socket = null; 67 private Socket monitor_socket = null;
68 private InputStream monitor_in = null; 68 private InputStream monitor_in = null;
69 private OutputStream monitor_out = null; 69 private OutputStream monitor_out = null;
70 private MyReader monitor_reader = null; 70 private MyReader monitor_reader = null;
71 private BlockingQueue<char[]> pending_commands = new ArrayBlockingQueue<char[]>(100); 71 private MyWriter monitor_writer = null;
72 private BlockingQueue<char[]> pending_commands = new ArrayBlockingQueue<char[]>(10000);
72 private MyServiceConnection monitor_connection = new MyServiceConnection(); 73 private MyServiceConnection monitor_connection = new MyServiceConnection();
74
75 class MyWriter extends Thread {
76 private OutputStream monitor_out;
77 private boolean is_closing = false;
78
79 public MyWriter(OutputStream monitor_out) {
80 this.monitor_out = monitor_out;
81 }
82
83 public void closing() {
84 is_closing = true;
85 this.interrupt();
86 }
87
88 public void run() {
89 char [] c;
90 try {
91 while (!is_closing) {
92 c = pending_commands.take();
93 c[0] = (char)(c.length - 1); // number of chars following
94 c[1] = cmd;
95 //Log.i(TAG, String.format("sending %d command", (int)cmd));
96 monitor_out.write(charsToBytes(c));
97 }
98 }
99 catch (InterruptedException e) {
100 if (!is_closing) Log.e(TAG, "exception in monitorWrite()", e);
101 }
102 catch (IOException e) {
103 Log.i(TAG, "exception in monitorWrite(), monitor died or closed the socket", e);
104 }
105
106 try {
107 monitor_out.close();
108 }
109 catch (IOException ee) {
110 Log.e(TAG, "exception in monitorWrite() closing output stream", ee);
111 }
112 monitor_out = null;
113 }
114 }
115
73 116
74 class MyReader extends Thread { 117 class MyReader extends Thread {
75 private InputStream monitor_in; 118 private InputStream monitor_in;
76 private byte[] b; 119 private byte[] b;
77 private boolean is_closing = false; 120 private boolean is_closing = false;
178 monitor_in = monitor_socket.getInputStream(); 221 monitor_in = monitor_socket.getInputStream();
179 monitor_out = monitor_socket.getOutputStream(); 222 monitor_out = monitor_socket.getOutputStream();
180 Log.i(TAG, "connected to monitor socket, send init " + init); 223 Log.i(TAG, "connected to monitor socket, send init " + init);
181 monitor_reader = new MyReader(monitor_in); 224 monitor_reader = new MyReader(monitor_in);
182 monitor_reader.start(); 225 monitor_reader.start();
226 monitor_writer = new MyWriter(monitor_out);
227 monitor_writer.start();
228
183 String x = " " + init; 229 String x = " " + init;
184 monitorWrite(MONITOR_CMD_INIT, x.toCharArray()); 230 monitorWrite(MONITOR_CMD_INIT, x.toCharArray());
185 char [] c; 231
186
187 while (true) {
188 c = pending_commands.poll();
189
190 if (c == null) break;
191
192 monitorWrite(c[1], c);
193 }
194 } 232 }
195 catch (IOException e) { 233 catch (IOException e) {
196 Log.e(TAG, "exception in onServiceConnected()", e); 234 Log.e(TAG, "exception in onServiceConnected()", e);
197 } 235 }
198 } 236 }
257 } 295 }
258 296
259 297
260 public void Disconnect() { 298 public void Disconnect() {
261 if (monitor_reader != null) monitor_reader.closing(); 299 if (monitor_reader != null) monitor_reader.closing();
262 300 if (monitor_writer != null) monitor_writer.closing();
263 try { 301 try {
264 if (monitor_out != null) monitor_out.close(); 302 if (monitor_out != null) monitor_out.close();
265 303
266 if (monitor_in != null) monitor_in.close(); 304 if (monitor_in != null) monitor_in.close();
267 305
309 347
310 return b; 348 return b;
311 } 349 }
312 350
313 351
314 public synchronized void monitorWrite(char cmd, char[] c) { 352 public void monitorWrite(char cmd, char[] c) {
315 try { 353 c[1] = cmd;
316 if (monitor_out != null) { 354 pending_commands.put(c);
317 c[0] = (char)(c.length - 1); // number of chars following
318 c[1] = cmd;
319 //Log.i(TAG, String.format("sending %d command", (int)cmd));
320 monitor_out.write(charsToBytes(c));
321 }
322 else {
323 c[1] = cmd;
324 pending_commands.put(c);
325 }
326 }
327 catch (InterruptedException e) {
328 Log.e(TAG, "exception in monitorWrite()", e);
329 }
330 catch (IOException e) {
331 Log.i(TAG, "exception in monitorWrite(), monitor died or closed the socket", e);
332
333 try {
334 monitor_out.close();
335 }
336 catch (IOException ee) {
337 Log.e(TAG, "exception in monitorWrite() closing output stream", ee);
338 }
339
340 monitor_out = null;
341 }
342 }; 355 };
343 356
344 public void resetWatch() { 357 public void resetWatch() {
345 start_line = 0; 358 start_line = 0;
346 end_line = 500; 359 end_line = 500;