# HG changeset patch # User Ilia Gromov # Date 1487530500 -10800 # Sun Feb 19 21:55:00 2017 +0300 # Branch release82 # Node ID 38d038db38f50896f71580c998cf6a2bbaf64a6e # Parent 6ab106cff4111eafc10cd5e1e8174205bd58acfe Fixing #267531 - Large pastes can lock up Term/AllOfNetBeans Fixing Java deadlock. (Maybe use piped stream instead?) diff --git a/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/StreamTerm.java b/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/StreamTerm.java --- a/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/StreamTerm.java +++ b/lib.terminalemulator/src/org/netbeans/lib/terminalemulator/StreamTerm.java @@ -55,6 +55,8 @@ import java.io.UnsupportedEncodingException; import java.io.Writer; import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; import java.util.logging.Level; import java.util.logging.Logger; @@ -99,48 +101,58 @@ */ private static final class InputMonitor implements TermInputListener { private final OutputStreamWriter outputStreamWriter; - + private final ExecutorService singlePool = Executors.newSingleThreadExecutor(); public InputMonitor(OutputStreamWriter outputStreamWriter) { this.outputStreamWriter = outputStreamWriter; } + + @Override + public void sendChars(final char c[], final int offset, final int count) { + singlePool.submit(new Runnable() { + @Override + public void run() { + try { + outputStreamWriter.write(c, offset, count); + outputStreamWriter.flush(); + } catch (IOException x) { + // no-op + } catch (Exception x) { + Logger.getLogger(StreamTerm.class.getName()).log(Level.SEVERE, null, x); + } + } + }); + } - @Override - public void sendChars(char c[], int offset, int count) { - try { - outputStreamWriter.write(c, offset, count); - outputStreamWriter.flush(); - } catch (IOException x) { - // no-op - } catch (Exception x) { - Logger.getLogger(StreamTerm.class.getName()).log(Level.SEVERE, null, x); - } - } - - @Override - public void sendChar(char c) { - try { - outputStreamWriter.write(c); - // writer is buffered, need to use flush! - // perhaps SHOULD use an unbuffered writer? - // Also fix send_chars() - outputStreamWriter.flush(); - } catch (IOException x) { - // no-op - } catch (Exception x) { - Logger.getLogger(StreamTerm.class.getName()).log(Level.SEVERE, null, x); - } - } + @Override + public void sendChar(final char c) { + singlePool.submit(new Runnable() { + @Override + public void run() { + try { + outputStreamWriter.write(c); + // writer is buffered, need to use flush! + // perhaps SHOULD use an unbuffered writer? + // Also fix send_chars() + outputStreamWriter.flush(); + } catch (IOException x) { + // no-op + } catch (Exception x) { + Logger.getLogger(StreamTerm.class.getName()).log(Level.SEVERE, null, x); + } + } + }); + } } - + public StreamTerm() { } + private static final int BUFSZ = 1024; /* * Monitor output from process and forward to terminal */ private static final class OutputMonitor extends Thread { - - private static final int BUFSZ = 1024; + private final char[] buf = new char[BUFSZ]; private final Term term; private final InputStreamReader reader; @@ -261,7 +273,6 @@ } } } - /** * Connect an I/O stream pair or triple to this Term. * Call disconnect() before attempting to connect() again.