Skip to content

Commit d69bf24

Browse files
committed
Fix BlockHound false positives related to channels that use locks
Solves #2302
1 parent 20ca97a commit d69bf24

File tree

1 file changed

+27
-5
lines changed

1 file changed

+27
-5
lines changed
Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,38 @@
11
@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
2+
23
package kotlinx.coroutines.debug
34

4-
import reactor.blockhound.BlockHound
55
import kotlinx.coroutines.scheduling.*
6+
import reactor.blockhound.*
67
import reactor.blockhound.integration.*
78

89
@Suppress("UNUSED")
9-
public class CoroutinesBlockHoundIntegration: BlockHoundIntegration {
10+
public class CoroutinesBlockHoundIntegration : BlockHoundIntegration {
1011

11-
override fun applyTo(builder: BlockHound.Builder) {
12-
builder.addDynamicThreadPredicate { isSchedulerWorker(it) }
13-
builder.nonBlockingThreadPredicate { p -> p.or { mayNotBlock(it) } }
12+
override fun applyTo(builder: BlockHound.Builder): Unit = with(builder) {
13+
allowBlockingCallsInside("kotlinx.coroutines.channels.AbstractSendChannel", "sendSuspend")
14+
// these classes use a lock internally
15+
for (method in listOf(
16+
"pollInternal", "isEmpty", "isFull", "isClosedForReceive", "offerInternal", "offerSelectInternal",
17+
"enqueueSend", "pollInternal", "pollSelectInternal", "enqueueReceiveInternal", "onCancelIdempotent" ))
18+
{
19+
allowBlockingCallsInside("kotlinx.coroutines.channels.ArrayChannel", method)
20+
}
21+
for (method in listOf("offerInternal", "offerSelectInternal", "updateHead")) {
22+
allowBlockingCallsInside("kotlinx.coroutines.channels.ArrayBroadcastChannel", method)
23+
}
24+
for (method in listOf("checkOffer", "pollInternal", "pollSelectInternal")) {
25+
allowBlockingCallsInside("kotlinx.coroutines.channels.ArrayBroadcastChannel\$Subscriber", method)
26+
}
27+
for (method in listOf("offerInternal", "offerSelectInternal", "pollInternal", "pollSelectInternal",
28+
"onCancelIdempotent"))
29+
{
30+
allowBlockingCallsInside("kotlinx.coroutines.channels.ConflatedChannel", method)
31+
}
32+
// should be safe; used for sending tasks to a thread pool
33+
allowBlockingCallsInside("java.util.concurrent.ScheduledThreadPoolExecutor", "execute")
34+
addDynamicThreadPredicate { isSchedulerWorker(it) }
35+
nonBlockingThreadPredicate { p -> p.or { mayNotBlock(it) } }
1436
}
1537

1638
}

0 commit comments

Comments
 (0)