Changed prompt interruption contract

Signed-off-by: Emmanuel Bigeon <emmanuel@bigeon.fr>
This commit is contained in:
2018-12-01 10:54:51 -05:00
parent c4bbfd8434
commit c206b5b22c
5 changed files with 86 additions and 18 deletions

View File

@@ -94,8 +94,7 @@ public interface ConsoleInput extends AutoCloseable {
/** Indicate to the input that is should interrompt the prompting, if possible.
* <p>
* The pending {@link #prompt()} or {@link #prompt(String)} operations should
* return immediatly. However the returned value can be anything (from the
* partial prompt content to an empty string or even a null pointer). */
* return immediately by throwing an InterruptedIOException. */
void interruptPrompt();
/** Test if the input is closed.

View File

@@ -111,6 +111,7 @@ public final class ReadingRunnable implements Runnable {
private final Map<String, Object> messageBlocker = new ConcurrentHashMap<>();
/** The lock. */
private final Object messageBlockerLock = new Object();
private boolean interrupting = false;
/** Create a reading runnable.
*
* @param reader the input to read from */
@@ -146,8 +147,7 @@ public final class ReadingRunnable implements Runnable {
public String getMessage() throws IOException {
synchronized (lock) {
if (!messages.isEmpty()) {
notifyMessage(messages.peek());
return messages.poll();
return pollMessage();
}
if (!running) {
throw new IOException(CLOSED_PIPE);
@@ -156,8 +156,7 @@ public final class ReadingRunnable implements Runnable {
waitMessage(TIMEOUT);
LOGGER.log(Level.FINEST, "Polled: {0}", messages.peek()); //$NON-NLS-1$
waiting = false;
notifyMessage(messages.peek());
return messages.poll();
return pollMessage();
}
}
@@ -169,8 +168,7 @@ public final class ReadingRunnable implements Runnable {
public String getNextMessage(final long timeout) throws IOException {
synchronized (lock) {
if (!messages.isEmpty()) {
notifyMessage(messages.peek());
return messages.poll();
return pollMessage();
}
if (!running) {
throw new IOException(CLOSED_PIPE);
@@ -181,10 +179,18 @@ public final class ReadingRunnable implements Runnable {
if (messages.isEmpty()) {
return null;
}
notifyMessage(messages.peek());
return messages.poll();
return pollMessage();
}
}
private String pollMessage() throws InterruptedIOException {
final String msg = messages.poll();
if (msg.isEmpty() && interrupting) {
throw new InterruptedIOException();
}
notifyMessage(msg);
return msg;
}
/** Wait for a message to be delivered.
*
@@ -221,7 +227,8 @@ public final class ReadingRunnable implements Runnable {
public void interrupt() {
synchronized (lock) {
if (waiting) {
messages.offer(""); //$NON-NLS-1$
messages.offer("");
interrupting = true;
lock.notifyAll();
}
}