From 892f26405c997d9235ec267f7ec002485be2437a Mon Sep 17 00:00:00 2001 From: "leonid.stashevsky" Date: Fri, 14 Oct 2022 11:30:05 +0200 Subject: [PATCH 1/2] KTOR-2914 Change exception type and clarify message --- .../src/io/ktor/network/selector/SelectorManagerSupport.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/ktor-network/jvm/src/io/ktor/network/selector/SelectorManagerSupport.kt b/ktor-network/jvm/src/io/ktor/network/selector/SelectorManagerSupport.kt index 132f2d9fc9..7ed8cba35c 100644 --- a/ktor-network/jvm/src/io/ktor/network/selector/SelectorManagerSupport.kt +++ b/ktor-network/jvm/src/io/ktor/network/selector/SelectorManagerSupport.kt @@ -4,6 +4,7 @@ package io.ktor.network.selector +import io.ktor.utils.io.errors.* import kotlinx.coroutines.* import java.nio.channels.* import java.nio.channels.spi.* @@ -35,12 +36,12 @@ public abstract class SelectorManagerSupport internal constructor() : SelectorMa val flag = interest.flag if (interestedOps and flag == 0) { val message = if (selectable.isClosed) { - "Selectable is closed" + "Selectable was closed concurrently" } else { "Selectable is invalid state: $interestedOps, $flag" } - throw IllegalArgumentException(message) + throw IOException(message) } suspendCancellableCoroutine { continuation -> From 2a017748eb4fef103a548e15245d8fe51f4d48a0 Mon Sep 17 00:00:00 2001 From: "leonid.stashevsky" Date: Mon, 24 Oct 2022 13:19:05 +0200 Subject: [PATCH 2/2] fixup! KTOR-2914 Change exception type and clarify message --- .../selector/SelectorManagerSupport.kt | 18 ++++---- .../selector/ActorSelectorManagerTest.kt | 43 +++++++++++++++++++ 2 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 ktor-network/jvm/test/io/ktor/network/selector/ActorSelectorManagerTest.kt diff --git a/ktor-network/jvm/src/io/ktor/network/selector/SelectorManagerSupport.kt b/ktor-network/jvm/src/io/ktor/network/selector/SelectorManagerSupport.kt index 7ed8cba35c..69d85422ac 100644 --- a/ktor-network/jvm/src/io/ktor/network/selector/SelectorManagerSupport.kt +++ b/ktor-network/jvm/src/io/ktor/network/selector/SelectorManagerSupport.kt @@ -34,15 +34,9 @@ public abstract class SelectorManagerSupport internal constructor() : SelectorMa public final override suspend fun select(selectable: Selectable, interest: SelectInterest) { val interestedOps = selectable.interestedOps val flag = interest.flag - if (interestedOps and flag == 0) { - val message = if (selectable.isClosed) { - "Selectable was closed concurrently" - } else { - "Selectable is invalid state: $interestedOps, $flag" - } - throw IOException(message) - } + if (selectable.isClosed) selectableIsClosed() + if (interestedOps and flag == 0) selectableIsInvalid(interestedOps, flag) suspendCancellableCoroutine { continuation -> continuation.invokeOnCancellation { @@ -180,3 +174,11 @@ public abstract class SelectorManagerSupport internal constructor() : SelectorMa public class ClosedSelectorCancellationException : CancellationException("Closed selector") } + +private fun selectableIsClosed(): Nothing { + throw IOException("Selectable is already closed") +} + +private fun selectableIsInvalid(interestedOps: Int, flag: Int): Nothing { + error("Selectable is invalid state: $interestedOps, $flag") +} diff --git a/ktor-network/jvm/test/io/ktor/network/selector/ActorSelectorManagerTest.kt b/ktor-network/jvm/test/io/ktor/network/selector/ActorSelectorManagerTest.kt new file mode 100644 index 0000000000..bf01ee79a6 --- /dev/null +++ b/ktor-network/jvm/test/io/ktor/network/selector/ActorSelectorManagerTest.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2014-2022 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license. + */ + +package io.ktor.network.selector + +import io.mockk.* +import kotlinx.coroutines.* +import org.junit.* +import org.junit.Test +import java.io.* +import kotlin.test.* + +class ActorSelectorManagerTest { + val manager = ActorSelectorManager(Dispatchers.Default) + + @After + fun tearDown() { + manager.close() + } + + @Test + fun testSelectableIsClosed(): Unit = runBlocking { + val selectable: Selectable = mockk() + every { selectable.interestedOps } returns SelectInterest.READ.flag + every { selectable.isClosed } returns true + + assertFailsWith { + manager.select(selectable, SelectInterest.READ) + } + } + + @Test + fun testSelectOnWrongInterest(): Unit = runBlocking { + val selectable: Selectable = mockk() + every { selectable.interestedOps } returns SelectInterest.READ.flag + every { selectable.isClosed } returns false + + assertFailsWith { + manager.select(selectable, SelectInterest.WRITE) + } + } +}