/** * Copyright (c) 2005-2012 by Appcelerator, Inc. All Rights Reserved. * Licensed under the terms of the Eclipse Public License (EPL). * Please see the license.txt included with this distribution for details. * Any modifications to this file must keep this entire header intact. */ package org.python.pydev.debug.model.remote; import java.io.IOException; import java.io.OutputStreamWriter; import java.net.Socket; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import org.python.pydev.core.log.Log; /** * Writer writes debugger commands to the network. Use postCommand to put new * ones in queue. */ public class DebuggerWriter implements Runnable { /** * connection socket */ private Socket socket; /** * a list of RemoteDebuggerCommands */ private List<AbstractDebuggerCommand> cmdQueue = new ArrayList<AbstractDebuggerCommand>(); private OutputStreamWriter out; /** * Volatile, as multiple threads may ask it to be 'done' */ private volatile boolean done = false; /** * Lock object for sleeping. */ private Object lock = new Object(); public DebuggerWriter(Socket s) throws IOException { socket = s; out = new OutputStreamWriter(s.getOutputStream(), StandardCharsets.UTF_8); } /** * Add command for processing */ public void postCommand(AbstractDebuggerCommand cmd) { synchronized (cmdQueue) { cmdQueue.add(cmd); } } public void done() { this.done = true; } /** * Loops and writes commands to the output */ @Override public void run() { while (!done) { AbstractDebuggerCommand cmd = null; synchronized (cmdQueue) { if (cmdQueue.size() > 0) { cmd = cmdQueue.remove(0); } } try { if (cmd != null) { String outgoing; try { outgoing = cmd.getOutgoing(); if (outgoing == null) { continue; } } catch (Throwable e) { Log.log(e); continue; } cmd.aboutToSend(); out.write(outgoing); out.write("\n"); out.flush(); } synchronized (lock) { Thread.sleep(100); } } catch (InterruptedException | IOException e) { done = true; } catch (Throwable e1) { Log.log(e1); //Unexpected error (but not done). } if ((socket == null) || !socket.isConnected()) { done = true; } } } }