[fix] Set waits inside loops

Signed-off-by: Emmanuel Bigeon <emmanuel@bigeon.fr>
This commit is contained in:
Emmanuel Bigeon 2021-11-12 09:50:51 +01:00
parent a9c97a7ebc
commit 66d25697a8
4 changed files with 56 additions and 63 deletions

View File

@ -142,15 +142,18 @@ public abstract class ForkTask implements Task {
* @param timeout the maximal time to join for (0 for ever) */ * @param timeout the maximal time to join for (0 for ever) */
public final void join(final ConsoleOutput out, final ConsoleInput in, public final void join(final ConsoleOutput out, final ConsoleInput in,
final long timeout) { final long timeout) {
final long tic = System.currentTimeMillis();
synchronized (runLock) { synchronized (runLock) {
this.out.connect(out); this.out.connect(out);
this.in.connect(in); this.in.connect(in);
try { long tac = System.currentTimeMillis() - tic;
if (running) { while (running && tac < timeout) {
try {
runLock.wait(timeout); runLock.wait(timeout);
} catch (final InterruptedException e) {
Thread.currentThread().interrupt();
} }
} catch (final InterruptedException e) { tac = System.currentTimeMillis() - tic;
Thread.currentThread().interrupt();
} }
this.out.disconnect(); this.out.disconnect();
this.in.disconnect(); this.in.disconnect();

View File

@ -286,10 +286,10 @@ public final class ConnectingConsoleInput implements ConsoleInput {
} }
private void getConnection(final long timeout) throws InterruptedIOException { private void getConnection(final long timeout) throws InterruptedIOException {
boolean connect; final long tic = System.currentTimeMillis();
synchronized (connectionLock) { synchronized (connectionLock) {
connect = connected != null; while ((connected == null || !interrupting)
if (!connect) { && (tic + timeout) > System.currentTimeMillis()) {
try { try {
connectionLock.wait(timeout); connectionLock.wait(timeout);
} catch (final InterruptedException e) { } catch (final InterruptedException e) {

View File

@ -75,51 +75,43 @@ public class ConnectingConsoleInputTest {
final ConnectingConsoleInput in = new ConnectingConsoleInput(); final ConnectingConsoleInput in = new ConnectingConsoleInput();
// Unconnected // Unconnected
final AtomicBoolean ended = new AtomicBoolean(false); final AtomicBoolean ended = new AtomicBoolean(false);
final TestFunction one = new TestFunction() { final TestFunction one = () -> {
try {
@Override final String res1 = in.prompt("m1", -1);
public void apply() throws Exception { fail("interruption of infinite waiting prompt should cause error, but was "
+ res1);
} catch (final InterruptedIOException e1) {
// ok
}
try {
final String res2 = in.prompt("m2", 25000);
fail("interruption of finite waiting prompt should cause error, but was "
+ res2);
} catch (final InterruptedIOException e2) {
// ok
}
synchronized (ended) {
ended.set(true);
try { try {
final String res = in.prompt("m1", -1); assertNull("Overtime should return null", in.prompt("m3", 200));
fail("interruption of infinite waiting prompt should cause error, but was " } catch (final InterruptedIOException e3) {
+ res); fail("Unexpected interruption error in overtime");
} catch (final InterruptedIOException e) {
// ok
}
try {
final String res = in.prompt("m2", 25000);
fail("interruption of finite waiting prompt should cause error, but was "
+ res);
} catch (final InterruptedIOException e) {
// ok
}
synchronized (ended) {
ended.set(true);
try {
assertNull("Overtime should return null", in.prompt("m3", 200));
} catch (final InterruptedIOException e) {
fail("Unexpected interruption error in overtime");
}
} }
} }
}; };
final ATestRunnable runnable = new FunctionalTestRunnable(one); final ATestRunnable runnable = new FunctionalTestRunnable(one);
final Thread th = new Thread(runnable); final Thread th = new Thread(runnable, "TestPromptSequence");
final Thread inter = new Thread(new Runnable() { final Thread inter = new Thread(() -> {
while (!ended.get()) {
@Override try {
public void run() { th.join(100);
while (!ended.get()) { } catch (final InterruptedException e) {
try { // TODO Auto-generated catch block
th.join(100); e.printStackTrace();
} catch (final InterruptedException e) { }
// TODO Auto-generated catch block synchronized (ended) {
e.printStackTrace(); if (!ended.get()) {
} in.interruptPrompt();
synchronized (ended) {
if (!ended.get()) {
in.interruptPrompt();
}
} }
} }
} }
@ -135,21 +127,17 @@ public class ConnectingConsoleInputTest {
in.connect(new StreamConsoleInput(null, pis, StandardCharsets.UTF_8)); in.connect(new StreamConsoleInput(null, pis, StandardCharsets.UTF_8));
final ATestRunnable runnable2 = new FunctionalTestRunnable(one); final ATestRunnable runnable2 = new FunctionalTestRunnable(one);
final Thread th2 = new Thread(runnable2); final Thread th2 = new Thread(runnable2);
final Thread inter2 = new Thread(new Runnable() { final Thread inter2 = new Thread(() -> {
while (!ended.get()) {
@Override try {
public void run() { th2.join(100);
while (!ended.get()) { } catch (final InterruptedException e) {
try { // TODO Auto-generated catch block
th2.join(100); e.printStackTrace();
} catch (final InterruptedException e) { }
// TODO Auto-generated catch block synchronized (ended) {
e.printStackTrace(); if (!ended.get()) {
} in.interruptPrompt();
synchronized (ended) {
if (!ended.get()) {
in.interruptPrompt();
}
} }
} }
} }

View File

@ -294,7 +294,9 @@ public final class PluggableConsoleInput implements ConsoleInput {
brutalDisconnection(); brutalDisconnection();
} }
} }
connexionLock.wait(connexionTimeout); while (!connected) {
connexionLock.wait(connexionTimeout);
}
} }
return null; return null;
} }