diff --git a/gclc-process/src/main/java/net/bigeon/gclc/process/io/ConnectingConsoleInput.java b/gclc-process/src/main/java/net/bigeon/gclc/process/io/ConnectingConsoleInput.java index e0c75b2..e21465f 100644 --- a/gclc-process/src/main/java/net/bigeon/gclc/process/io/ConnectingConsoleInput.java +++ b/gclc-process/src/main/java/net/bigeon/gclc/process/io/ConnectingConsoleInput.java @@ -193,39 +193,7 @@ public final class ConnectingConsoleInput implements ConsoleInput { synchronized (promptLock) { prompting = true; } - while (true) { - if (!checkPrompt()) { - return null; - } - getConnection(0); - boolean connect; - ConsoleInput actualConnected; - synchronized (connectionLock) { - connect = connected != null; - actualConnected = connected; - } - if (!connect) { - continue; - } - try { - final String res = actualConnected.prompt(message); - synchronized (promptLock) { - if (prompting) { - prompting = false; - return res; - } - } - } catch (final InterruptedIOException e) { - // The inner console was interrupted. This can mean we are - // disconnecting or actually interrupted. - if (disconnection) { - disconnection = false; - } else { - interrupting = false; - throw e; - } - } - } + return doPrompt(message, 0, 0); } /* (non-Javadoc) @@ -238,12 +206,17 @@ public final class ConnectingConsoleInput implements ConsoleInput { synchronized (promptLock) { prompting = true; } - final long end = System.currentTimeMillis() + timeout; + final long tic = System.currentTimeMillis(); + return doPrompt(message, timeout, tic); + } + + private String doPrompt(final String message, final long timeout, final long tic) + throws InterruptedIOException, IOException { do { if (!checkPrompt()) { break; } - getConnection(timeout); + getConnection(getTimeoutLeft(tic, timeout)); boolean connect; ConsoleInput actualConnected; synchronized (connectionLock) { @@ -254,8 +227,13 @@ public final class ConnectingConsoleInput implements ConsoleInput { continue; } try { - final String res = actualConnected.prompt(message, - end - System.currentTimeMillis()); + final long timeoutLeft = getTimeoutLeft(tic, timeout); + final String res; + if (timeoutLeft == 0) { + res = actualConnected.prompt(message); + } else { + res = actualConnected.prompt(message, timeoutLeft); + } synchronized (promptLock) { if (prompting) { prompting = false; @@ -272,21 +250,33 @@ public final class ConnectingConsoleInput implements ConsoleInput { throw e; } } - } while (System.currentTimeMillis() < end); + } while (checkTimeout(tic, timeout)); return null; } + private static boolean checkTimeout(final long tic, final long timeout) { + return timeout <= 0 || tic + timeout > System.currentTimeMillis(); + } + + private static long getTimeoutLeft(final long tic, final long timeout) { + if (timeout > 0) { + return Math.max(timeout + tic - System.currentTimeMillis(), 1); + } + if (timeout < 0) { + return 1; + } + return 0; + } + /** Test if we are in prompting state. * * @return if the process is currently in prompting state. * @throws InterruptedIOException if the prompting state has been interrupted */ private boolean checkPrompt() throws InterruptedIOException { synchronized (promptLock) { - if (!prompting) { - if (interrupting) { - interrupting = false; - throw new InterruptedIOException("Prompt was interrupted"); - } + if (!prompting && interrupting) { + interrupting = false; + throw new InterruptedIOException("Prompt was interrupted"); } return prompting; }