From ba07cbefe6c94f4767ee97c6e642ad6e3e5f16aa Mon Sep 17 00:00:00 2001 From: Jordan Stewart Date: Fri, 14 Feb 2020 08:00:01 +0000 Subject: [PATCH 1/4] Throw new InterruptedIOException subtype on timeout Introduces TimeoutException which a caller can catch if it just wants to just deal with timeout and deadline reached, but not interrupts. --- okio/src/jvmMain/kotlin/okio/Timeout.kt | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/okio/src/jvmMain/kotlin/okio/Timeout.kt b/okio/src/jvmMain/kotlin/okio/Timeout.kt index 8241f7f34d..7ed0dde689 100644 --- a/okio/src/jvmMain/kotlin/okio/Timeout.kt +++ b/okio/src/jvmMain/kotlin/okio/Timeout.kt @@ -19,6 +19,8 @@ import java.io.IOException import java.io.InterruptedIOException import java.util.concurrent.TimeUnit +class TimeoutException(message: String) : InterruptedIOException(message) + actual open class Timeout { /** * True if `deadlineNanoTime` is defined. There is no equivalent to null or 0 for @@ -87,9 +89,9 @@ actual open class Timeout { } /** - * Throws an [InterruptedIOException] if the deadline has been reached or if the current thread - * has been interrupted. This method doesn't detect timeouts; that should be implemented to - * asynchronously abort an in-progress operation. + * Throws a [TimeoutException] if the deadline has been reached or an [InterruptedIOException] if + * the current thread has been interrupted. This method doesn't detect timeouts; that should be + * implemented to asynchronously abort an in-progress operation. */ @Throws(IOException::class) open fun throwIfReached() { @@ -99,14 +101,14 @@ actual open class Timeout { } if (hasDeadline && deadlineNanoTime - System.nanoTime() <= 0) { - throw InterruptedIOException("deadline reached") + throw TimeoutException("deadline reached") } } /** - * Waits on `monitor` until it is notified. Throws [InterruptedIOException] if either the thread - * is interrupted or if this timeout elapses before `monitor` is notified. The caller must be - * synchronized on `monitor`. + * Waits on `monitor` until it is notified. Throws [InterruptedIOException] if the thread is + * interrupted or [TimeoutException] if this timeout elapses before `monitor` is notified. The + * caller must be synchronized on `monitor`. * * Here's a sample class that uses `waitUntilNotified()` to await a specific state. Note that the * call is made within a loop to avoid unnecessary waiting and to mitigate spurious notifications. @@ -170,7 +172,7 @@ actual open class Timeout { // Throw if the timeout elapsed before the monitor was notified. if (elapsedNanos >= waitNanos) { - throw InterruptedIOException("timeout") + throw TimeoutException("timeout") } } catch (e: InterruptedException) { Thread.currentThread().interrupt() // Retain interrupted status. From 491a5aec26011e693cee9953aff460574a24867f Mon Sep 17 00:00:00 2001 From: Jordan Stewart Date: Sat, 15 Feb 2020 14:32:30 +0000 Subject: [PATCH 2/4] Ensure new TimeoutException continues to be thrown in future --- okio/src/jvmTest/java/okio/PipeTest.java | 5 ++--- .../java/okio/WaitUntilNotifiedTest.java | 20 +++++++++---------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/okio/src/jvmTest/java/okio/PipeTest.java b/okio/src/jvmTest/java/okio/PipeTest.java index 6e17e3f224..c54e7b2b96 100644 --- a/okio/src/jvmTest/java/okio/PipeTest.java +++ b/okio/src/jvmTest/java/okio/PipeTest.java @@ -16,7 +16,6 @@ package okio; import java.io.IOException; -import java.io.InterruptedIOException; import java.util.Random; import java.util.concurrent.Callable; import java.util.concurrent.Executors; @@ -109,7 +108,7 @@ public final class PipeTest { try { pipe.sink().write(new Buffer().writeUtf8("def"), 3L); fail(); - } catch (InterruptedIOException expected) { + } catch (TimeoutException expected) { assertEquals("timeout", expected.getMessage()); } assertElapsed(1000.0, start); @@ -127,7 +126,7 @@ public final class PipeTest { try { pipe.source().read(readBuffer, 6L); fail(); - } catch (InterruptedIOException expected) { + } catch (TimeoutException expected) { assertEquals("timeout", expected.getMessage()); } assertElapsed(1000.0, start); diff --git a/okio/src/jvmTest/java/okio/WaitUntilNotifiedTest.java b/okio/src/jvmTest/java/okio/WaitUntilNotifiedTest.java index 0263aabdb2..d17b9c0251 100644 --- a/okio/src/jvmTest/java/okio/WaitUntilNotifiedTest.java +++ b/okio/src/jvmTest/java/okio/WaitUntilNotifiedTest.java @@ -50,33 +50,33 @@ public final class WaitUntilNotifiedTest { assertElapsed(1000.0, start); } - @Test public synchronized void timeout() { + @Test public synchronized void timeout() throws InterruptedIOException { Timeout timeout = new Timeout(); timeout.timeout(1000, TimeUnit.MILLISECONDS); double start = now(); try { timeout.waitUntilNotified(this); fail(); - } catch (InterruptedIOException expected) { + } catch (TimeoutException expected) { assertEquals("timeout", expected.getMessage()); } assertElapsed(1000.0, start); } - @Test public synchronized void deadline() { + @Test public synchronized void deadline() throws InterruptedIOException { Timeout timeout = new Timeout(); timeout.deadline(1000, TimeUnit.MILLISECONDS); double start = now(); try { timeout.waitUntilNotified(this); fail(); - } catch (InterruptedIOException expected) { + } catch (TimeoutException expected) { assertEquals("timeout", expected.getMessage()); } assertElapsed(1000.0, start); } - @Test public synchronized void deadlineBeforeTimeout() { + @Test public synchronized void deadlineBeforeTimeout() throws InterruptedIOException { Timeout timeout = new Timeout(); timeout.timeout(5000, TimeUnit.MILLISECONDS); timeout.deadline(1000, TimeUnit.MILLISECONDS); @@ -84,13 +84,13 @@ public final class WaitUntilNotifiedTest { try { timeout.waitUntilNotified(this); fail(); - } catch (InterruptedIOException expected) { + } catch (TimeoutException expected) { assertEquals("timeout", expected.getMessage()); } assertElapsed(1000.0, start); } - @Test public synchronized void timeoutBeforeDeadline() { + @Test public synchronized void timeoutBeforeDeadline() throws InterruptedIOException { Timeout timeout = new Timeout(); timeout.timeout(1000, TimeUnit.MILLISECONDS); timeout.deadline(5000, TimeUnit.MILLISECONDS); @@ -98,20 +98,20 @@ public final class WaitUntilNotifiedTest { try { timeout.waitUntilNotified(this); fail(); - } catch (InterruptedIOException expected) { + } catch (TimeoutException expected) { assertEquals("timeout", expected.getMessage()); } assertElapsed(1000.0, start); } - @Test public synchronized void deadlineAlreadyReached() { + @Test public synchronized void deadlineAlreadyReached() throws InterruptedIOException { Timeout timeout = new Timeout(); timeout.deadlineNanoTime(System.nanoTime()); double start = now(); try { timeout.waitUntilNotified(this); fail(); - } catch (InterruptedIOException expected) { + } catch (TimeoutException expected) { assertEquals("timeout", expected.getMessage()); } assertElapsed(0.0, start); From 8119fa3b64ec4d11022ff9ca8e16bd4a621fb50a Mon Sep 17 00:00:00 2001 From: Jordan Stewart Date: Sat, 15 Feb 2020 14:37:15 +0000 Subject: [PATCH 3/4] Throw TimeoutException for async timeouts --- okio/src/jvmMain/kotlin/okio/AsyncTimeout.kt | 6 ++---- okio/src/jvmTest/java/okio/AsyncTimeoutTest.java | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/okio/src/jvmMain/kotlin/okio/AsyncTimeout.kt b/okio/src/jvmMain/kotlin/okio/AsyncTimeout.kt index 65d52fd666..0aed2ab647 100644 --- a/okio/src/jvmMain/kotlin/okio/AsyncTimeout.kt +++ b/okio/src/jvmMain/kotlin/okio/AsyncTimeout.kt @@ -16,7 +16,6 @@ package okio import java.io.IOException -import java.io.InterruptedIOException import java.util.concurrent.TimeUnit /** @@ -163,11 +162,10 @@ open class AsyncTimeout : Timeout() { /** * Returns an [IOException] to represent a timeout. By default this method returns - * [InterruptedIOException]. If [cause] is non-null it is set as the cause of the - * returned exception. + * [TimeoutException]. If [cause] is non-null it is set as the cause of the returned exception. */ protected open fun newTimeoutException(cause: IOException?): IOException { - val e = InterruptedIOException("timeout") + val e = TimeoutException("timeout") if (cause != null) { e.initCause(cause) } diff --git a/okio/src/jvmTest/java/okio/AsyncTimeoutTest.java b/okio/src/jvmTest/java/okio/AsyncTimeoutTest.java index 3f31e2bc4f..ae9643c11e 100644 --- a/okio/src/jvmTest/java/okio/AsyncTimeoutTest.java +++ b/okio/src/jvmTest/java/okio/AsyncTimeoutTest.java @@ -301,7 +301,7 @@ public final class AsyncTimeoutTest { try { timeoutSink.write(data, 1); fail(); - } catch (InterruptedIOException expected) { + } catch (TimeoutException expected) { assertEquals("timeout", expected.getMessage()); assertEquals("exception and timeout", expected.getCause().getMessage()); } From b3c5cdb18db3a26985b9a6f54aaefab2dbe44000 Mon Sep 17 00:00:00 2001 From: Jordan Stewart Date: Sat, 15 Feb 2020 15:27:14 +0000 Subject: [PATCH 4/4] Ensure new TimeoutException continues to be thrown in future --- okio/src/jvmTest/java/okio/AsyncTimeoutTest.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/okio/src/jvmTest/java/okio/AsyncTimeoutTest.java b/okio/src/jvmTest/java/okio/AsyncTimeoutTest.java index ae9643c11e..1ba7ed6ed8 100644 --- a/okio/src/jvmTest/java/okio/AsyncTimeoutTest.java +++ b/okio/src/jvmTest/java/okio/AsyncTimeoutTest.java @@ -16,7 +16,6 @@ package okio; import java.io.IOException; -import java.io.InterruptedIOException; import java.util.Arrays; import java.util.List; import java.util.Random; @@ -198,7 +197,7 @@ public final class AsyncTimeoutTest { try { timeoutSink.write(data, 1); fail(); - } catch (InterruptedIOException expected) { + } catch (TimeoutException expected) { } } @@ -218,7 +217,7 @@ public final class AsyncTimeoutTest { try { timeoutSink.flush(); fail(); - } catch (InterruptedIOException expected) { + } catch (TimeoutException expected) { } } @@ -238,7 +237,7 @@ public final class AsyncTimeoutTest { try { timeoutSink.close(); fail(); - } catch (InterruptedIOException expected) { + } catch (TimeoutException expected) { } } @@ -259,7 +258,7 @@ public final class AsyncTimeoutTest { try { timeoutSource.read(new Buffer(), 0); fail(); - } catch (InterruptedIOException expected) { + } catch (TimeoutException expected) { } } @@ -279,7 +278,7 @@ public final class AsyncTimeoutTest { try { timeoutSource.close(); fail(); - } catch (InterruptedIOException expected) { + } catch (TimeoutException expected) { } }