Skip to content

Commit 88aa2fe

Browse files
committed
Implement runBlockingNonInterruptible in tests and test it
1 parent 4503d2a commit 88aa2fe

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

kotlinx-coroutines-core/jvm/test/RunBlockingJvmTest.kt

+35
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,27 @@ class RunBlockingJvmTest : TestBase() {
6464
finish(5)
6565
}
6666

67+
/**
68+
* Tests that [runBlockingNonInterruptible] is going to run its job to completion even if it gets interrupted
69+
* or if thread switches occur.
70+
*/
71+
@Test
72+
fun testNonInterruptibleRunBlocking() {
73+
startInSeparateThreadAndInterrupt { mayInterrupt ->
74+
val v = runBlockingNonInterruptible {
75+
mayInterrupt()
76+
repeat(10) {
77+
expect(it + 1)
78+
delay(1)
79+
}
80+
42
81+
}
82+
assertEquals(42, v)
83+
expect(11)
84+
}
85+
finish(12)
86+
}
87+
6788
private fun startInSeparateThreadAndInterrupt(action: (mayInterrupt: () -> Unit) -> Unit) {
6889
val latch = CountDownLatch(1)
6990
val thread = thread {
@@ -73,4 +94,18 @@ class RunBlockingJvmTest : TestBase() {
7394
thread.interrupt()
7495
thread.join()
7596
}
97+
98+
private fun <T> runBlockingNonInterruptible(action: suspend () -> T): T {
99+
val deferred = CompletableDeferred<T>()
100+
try {
101+
runBlocking {
102+
withContext(NonCancellable) {
103+
deferred.completeWith(runCatching { action() })
104+
}
105+
}
106+
} catch (_: InterruptedException) {
107+
Thread.currentThread().interrupt() // restore the interrupted flag
108+
}
109+
return deferred.getCompleted()
110+
}
76111
}

0 commit comments

Comments
 (0)