Fixed readline mixing with previous readchar executions
This commit is contained in:
parent
227a0d9378
commit
c6e4d813a7
@ -8,7 +8,9 @@ import java.io.PrintStream;
|
|||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.security.CodeSource;
|
import java.security.CodeSource;
|
||||||
import java.security.ProtectionDomain;
|
import java.security.ProtectionDomain;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import org.fusesource.jansi.Ansi;
|
import org.fusesource.jansi.Ansi;
|
||||||
import org.fusesource.jansi.AnsiConsole;
|
import org.fusesource.jansi.AnsiConsole;
|
||||||
@ -104,13 +106,13 @@ public class InputConsole {
|
|||||||
return consoleProxyReader.echo0();
|
return consoleProxyReader.echo0();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final ReentrantLock inputLock = new ReentrantLock();
|
||||||
private final Object inputLockSingle = new Object();
|
private final Object inputLockSingle = new Object();
|
||||||
private final Object inputLockLine = new Object();
|
private final Object inputLockLine = new Object();
|
||||||
|
|
||||||
private final ObjectPool<ByteBuffer2> pool = ObjectPoolFactory.create(new ByteBuffer2Poolable());
|
private final ObjectPool<ByteBuffer2> pool = ObjectPoolFactory.create(new ByteBuffer2Poolable());
|
||||||
private ThreadLocal<ObjectPoolHolder<ByteBuffer2>> threadBufferForRead = new ThreadLocal<ObjectPoolHolder<ByteBuffer2>>();
|
private ThreadLocal<ObjectPoolHolder<ByteBuffer2>> threadBuffer = new ThreadLocal<ObjectPoolHolder<ByteBuffer2>>();
|
||||||
private CopyOnWriteArrayList<ObjectPoolHolder<ByteBuffer2>> threadBuffersForRead = new CopyOnWriteArrayList<ObjectPoolHolder<ByteBuffer2>>();
|
private List<ObjectPoolHolder<ByteBuffer2>> threadBuffersForRead = new CopyOnWriteArrayList<ObjectPoolHolder<ByteBuffer2>>();
|
||||||
|
|
||||||
private volatile int readChar = -1;
|
private volatile int readChar = -1;
|
||||||
private final Terminal terminal;
|
private final Terminal terminal;
|
||||||
@ -120,7 +122,7 @@ public class InputConsole {
|
|||||||
|
|
||||||
String type = System.getProperty(TerminalType.TYPE, TerminalType.AUTO).toLowerCase();
|
String type = System.getProperty(TerminalType.TYPE, TerminalType.AUTO).toLowerCase();
|
||||||
if ("dumb".equals(System.getenv("TERM"))) {
|
if ("dumb".equals(System.getenv("TERM"))) {
|
||||||
type = "none";
|
type = TerminalType.NONE;
|
||||||
logger.debug("$TERM=dumb; setting type={}", type);
|
logger.debug("$TERM=dumb; setting type={}", type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -205,13 +207,44 @@ public class InputConsole {
|
|||||||
return this.terminal.isEchoEnabled();
|
return this.terminal.isEchoEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** return -1 if no data or bunged-up */
|
||||||
|
private final int read0() {
|
||||||
|
synchronized (this.inputLockSingle) {
|
||||||
|
try {
|
||||||
|
this.inputLockSingle.wait();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** return null if no data */
|
return this.readChar;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** return empty char[] if no data */
|
||||||
|
private final char[] readLinePassword0() {
|
||||||
|
// don't bother in an IDE. it won't work.
|
||||||
|
boolean echoEnabled = this.terminal.isEchoEnabled();
|
||||||
|
this.terminal.setEchoEnabled(false);
|
||||||
|
char[] readLine0 = readLine0();
|
||||||
|
this.terminal.setEchoEnabled(echoEnabled);
|
||||||
|
|
||||||
|
return readLine0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** return empty char[] if no data */
|
||||||
private final char[] readLine0() {
|
private final char[] readLine0() {
|
||||||
if (this.threadBufferForRead.get() == null) {
|
synchronized (this.inputLock) {
|
||||||
|
// empty here, because we don't want to register a readLine WHILE we are still processing
|
||||||
|
// the current line info.
|
||||||
|
|
||||||
|
// the threadBufferForRead getting added is the part that is important
|
||||||
|
if (this.threadBuffer.get() == null) {
|
||||||
ObjectPoolHolder<ByteBuffer2> holder = this.pool.take();
|
ObjectPoolHolder<ByteBuffer2> holder = this.pool.take();
|
||||||
this.threadBufferForRead.set(holder);
|
this.threadBuffer.set(holder);
|
||||||
this.threadBuffersForRead.add(holder);
|
this.threadBuffersForRead.add(holder);
|
||||||
|
} else {
|
||||||
|
this.threadBuffer.get().getValue().clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
synchronized (this.inputLockLine) {
|
synchronized (this.inputLockLine) {
|
||||||
@ -222,7 +255,7 @@ public class InputConsole {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectPoolHolder<ByteBuffer2> objectPoolHolder = this.threadBufferForRead.get();
|
ObjectPoolHolder<ByteBuffer2> objectPoolHolder = this.threadBuffer.get();
|
||||||
ByteBuffer2 buffer = objectPoolHolder.getValue();
|
ByteBuffer2 buffer = objectPoolHolder.getValue();
|
||||||
int len = buffer.position();
|
int len = buffer.position();
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
@ -237,35 +270,11 @@ public class InputConsole {
|
|||||||
|
|
||||||
this.threadBuffersForRead.remove(objectPoolHolder);
|
this.threadBuffersForRead.remove(objectPoolHolder);
|
||||||
this.pool.release(objectPoolHolder);
|
this.pool.release(objectPoolHolder);
|
||||||
this.threadBufferForRead.set(null);
|
this.threadBuffer.set(null);
|
||||||
|
|
||||||
return readChars;
|
return readChars;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** return null if no data */
|
|
||||||
private final char[] readLinePassword0() {
|
|
||||||
// don't bother in an IDE. it won't work.
|
|
||||||
boolean echoEnabled = this.terminal.isEchoEnabled();
|
|
||||||
this.terminal.setEchoEnabled(false);
|
|
||||||
char[] readLine0 = readLine0();
|
|
||||||
this.terminal.setEchoEnabled(echoEnabled);
|
|
||||||
|
|
||||||
return readLine0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** return -1 if no data */
|
|
||||||
private final int read0() {
|
|
||||||
synchronized (this.inputLockSingle) {
|
|
||||||
try {
|
|
||||||
this.inputLockSingle.wait();
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.readChar;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* releases any thread still waiting.
|
* releases any thread still waiting.
|
||||||
*/
|
*/
|
||||||
@ -292,6 +301,9 @@ public class InputConsole {
|
|||||||
// don't type ; in a bash shell, it quits everything
|
// don't type ; in a bash shell, it quits everything
|
||||||
// \n is replaced by \r in unix terminal?
|
// \n is replaced by \r in unix terminal?
|
||||||
while ((typedChar = this.terminal.read()) != -1) {
|
while ((typedChar = this.terminal.read()) != -1) {
|
||||||
|
synchronized (this.inputLock) {
|
||||||
|
// don't let anyone add a new reader while we are still processing the current actions
|
||||||
|
|
||||||
asChar = (char) typedChar;
|
asChar = (char) typedChar;
|
||||||
|
|
||||||
if (logger2.isTraceEnabled()) {
|
if (logger2.isTraceEnabled()) {
|
||||||
@ -363,9 +375,9 @@ public class InputConsole {
|
|||||||
this.inputLockLine.notifyAll();
|
this.inputLockLine.notifyAll();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// only append if we are not a new line.
|
||||||
// our windows console PREVENTS us from returning '\r' (it truncates '\r\n', and returns just '\n')
|
// our windows console PREVENTS us from returning '\r' (it truncates '\r\n', and returns just '\n')
|
||||||
|
|
||||||
// only append if we are not a new line.
|
|
||||||
for (ObjectPoolHolder<ByteBuffer2> objectPoolHolder : this.threadBuffersForRead) {
|
for (ObjectPoolHolder<ByteBuffer2> objectPoolHolder : this.threadBuffersForRead) {
|
||||||
ByteBuffer2 buffer = objectPoolHolder.getValue();
|
ByteBuffer2 buffer = objectPoolHolder.getValue();
|
||||||
buffer.writeChar(asChar);
|
buffer.writeChar(asChar);
|
||||||
@ -373,6 +385,7 @@ public class InputConsole {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* try to guess if we are running inside an IDE
|
* try to guess if we are running inside an IDE
|
||||||
|
Loading…
Reference in New Issue
Block a user