Fix BlockHound false-positive in ConflatedChannel (#2881)
Fixes #2866
diff --git a/kotlinx-coroutines-debug/src/CoroutinesBlockHoundIntegration.kt b/kotlinx-coroutines-debug/src/CoroutinesBlockHoundIntegration.kt
index e090556..e13bc06 100644
--- a/kotlinx-coroutines-debug/src/CoroutinesBlockHoundIntegration.kt
+++ b/kotlinx-coroutines-debug/src/CoroutinesBlockHoundIntegration.kt
@@ -135,7 +135,7 @@
*/
private fun BlockHound.Builder.allowBlockingCallsInConflatedChannel() {
for (method in listOf("offerInternal", "offerSelectInternal", "pollInternal", "pollSelectInternal",
- "onCancelIdempotent"))
+ "onCancelIdempotent", "isEmpty", "enqueueReceiveInternal"))
{
allowBlockingCallsInside("kotlinx.coroutines.channels.ConflatedChannel", method)
}
diff --git a/kotlinx-coroutines-debug/test/BlockHoundTest.kt b/kotlinx-coroutines-debug/test/BlockHoundTest.kt
index 571daca..3f58878 100644
--- a/kotlinx-coroutines-debug/test/BlockHoundTest.kt
+++ b/kotlinx-coroutines-debug/test/BlockHoundTest.kt
@@ -4,6 +4,7 @@
import org.junit.*
import reactor.blockhound.*
+@Suppress("UnusedEquals", "DeferredResultUnused", "BlockingMethodInNonBlockingContext")
class BlockHoundTest : TestBase() {
@Before
@@ -12,21 +13,21 @@
}
@Test(expected = BlockingOperationError::class)
- fun shouldDetectBlockingInDefault() = runTest {
+ fun testShouldDetectBlockingInDefault() = runTest {
withContext(Dispatchers.Default) {
Thread.sleep(1)
}
}
@Test
- fun shouldNotDetectBlockingInIO() = runTest {
+ fun testShouldNotDetectBlockingInIO() = runTest {
withContext(Dispatchers.IO) {
Thread.sleep(1)
}
}
@Test
- fun shouldNotDetectNonblocking() = runTest {
+ fun testShouldNotDetectNonblocking() = runTest {
withContext(Dispatchers.Default) {
val a = 1
val b = 2
@@ -54,7 +55,7 @@
}
@Test
- fun testChannelsNotBeingConsideredBlocking() = runTest {
+ fun testChannelNotBeingConsideredBlocking() = runTest {
withContext(Dispatchers.Default) {
// Copy of kotlinx.coroutines.channels.ArrayChannelTest.testSimple
val q = Channel<Int>(1)
@@ -74,6 +75,24 @@
}
}
+ @Test
+ fun testConflatedChannelsNotBeingConsideredBlocking() = runTest {
+ withContext(Dispatchers.Default) {
+ val q = Channel<Int>(Channel.CONFLATED)
+ check(q.isEmpty)
+ check(!q.isClosedForReceive)
+ check(!q.isClosedForSend)
+ val sender = launch {
+ q.send(1)
+ }
+ val receiver = launch {
+ q.receive() == 1
+ }
+ sender.join()
+ receiver.join()
+ }
+ }
+
@Test(expected = BlockingOperationError::class)
fun testReusingThreadsFailure() = runTest {
val n = 100