From ed023f6027edd9856c71985493101665c4567024 Mon Sep 17 00:00:00 2001 From: Abduqodiri Qurbonzoda Date: Tue, 8 Oct 2024 11:41:22 +0300 Subject: [PATCH 1/2] Fix K/N EvenLoop.reschedule time conversion A "point of time" value was wrongly passed to a function that expects a "duration of time". Additionally, the former was in nanos, while the later in milllis. --- kotlinx-coroutines-core/native/src/EventLoop.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kotlinx-coroutines-core/native/src/EventLoop.kt b/kotlinx-coroutines-core/native/src/EventLoop.kt index 4265f6094f..a5ad5a7155 100644 --- a/kotlinx-coroutines-core/native/src/EventLoop.kt +++ b/kotlinx-coroutines-core/native/src/EventLoop.kt @@ -15,7 +15,8 @@ internal actual abstract class EventLoopImplPlatform : EventLoop() { } protected actual fun reschedule(now: Long, delayedTask: EventLoopImplBase.DelayedTask) { - DefaultExecutor.invokeOnTimeout(now, delayedTask, EmptyCoroutineContext) + val delayTimeMillis = delayNanosToMillis(nanoTime() - now) + DefaultExecutor.invokeOnTimeout(delayTimeMillis, delayedTask, EmptyCoroutineContext) } } From 7eaa68b70242dddd2cace5ddb0a8f528ba48bb14 Mon Sep 17 00:00:00 2001 From: Abduqodiri Qurbonzoda Date: Thu, 17 Oct 2024 12:16:42 +0300 Subject: [PATCH 2/2] fixup! Fix K/N EvenLoop.reschedule time conversion --- .../concurrent/test/RunBlockingTest.kt | 18 ++++++++++++++++++ .../native/src/EventLoop.kt | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/kotlinx-coroutines-core/concurrent/test/RunBlockingTest.kt b/kotlinx-coroutines-core/concurrent/test/RunBlockingTest.kt index f04b491c6d..43f7976ffa 100644 --- a/kotlinx-coroutines-core/concurrent/test/RunBlockingTest.kt +++ b/kotlinx-coroutines-core/concurrent/test/RunBlockingTest.kt @@ -4,6 +4,8 @@ import kotlinx.coroutines.testing.* import kotlinx.coroutines.exceptions.* import kotlin.coroutines.* import kotlin.test.* +import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.seconds class RunBlockingTest : TestBase() { @@ -176,4 +178,20 @@ class RunBlockingTest : TestBase() { } } } + + /** Tests that the delayed tasks scheduled on a closed `runBlocking` event loop get processed in reasonable time. */ + @Test + fun testReschedulingDelayedTasks() { + val job = runBlocking { + val dispatcher = coroutineContext[ContinuationInterceptor]!! + GlobalScope.launch(dispatcher) { + delay(1.milliseconds) + } + } + runBlocking { + withTimeout(10.seconds) { + job.join() + } + } + } } diff --git a/kotlinx-coroutines-core/native/src/EventLoop.kt b/kotlinx-coroutines-core/native/src/EventLoop.kt index a5ad5a7155..58128d52fd 100644 --- a/kotlinx-coroutines-core/native/src/EventLoop.kt +++ b/kotlinx-coroutines-core/native/src/EventLoop.kt @@ -15,7 +15,7 @@ internal actual abstract class EventLoopImplPlatform : EventLoop() { } protected actual fun reschedule(now: Long, delayedTask: EventLoopImplBase.DelayedTask) { - val delayTimeMillis = delayNanosToMillis(nanoTime() - now) + val delayTimeMillis = delayNanosToMillis(delayedTask.nanoTime - now) DefaultExecutor.invokeOnTimeout(delayTimeMillis, delayedTask, EmptyCoroutineContext) } }