From 6e493c4e1443b021855ddaadfca37f017e7f077f Mon Sep 17 00:00:00 2001 From: Dmitry Khalanskiy Date: Thu, 8 Sep 2022 14:46:38 +0200 Subject: [PATCH] Fix another potential memory leak in WorkerDispatcher --- .../native/src/MultithreadedDispatchers.kt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/kotlinx-coroutines-core/native/src/MultithreadedDispatchers.kt b/kotlinx-coroutines-core/native/src/MultithreadedDispatchers.kt index a940dcbdb0..c0b82aece0 100644 --- a/kotlinx-coroutines-core/native/src/MultithreadedDispatchers.kt +++ b/kotlinx-coroutines-core/native/src/MultithreadedDispatchers.kt @@ -26,12 +26,16 @@ internal class WorkerDispatcher(name: String) : CloseableCoroutineDispatcher(), } override fun scheduleResumeAfterDelay(timeMillis: Long, continuation: CancellableContinuation) { - worker.executeAfter(timeMillis.toMicrosSafe()) { + val handle = schedule(timeMillis, Runnable { with(continuation) { resumeUndispatched(Unit) } - } + }) + continuation.disposeOnCancellation(handle) } - override fun invokeOnTimeout(timeMillis: Long, block: Runnable, context: CoroutineContext): DisposableHandle { + override fun invokeOnTimeout(timeMillis: Long, block: Runnable, context: CoroutineContext): DisposableHandle = + schedule(timeMillis, block) + + private fun schedule(timeMillis: Long, block: Runnable): DisposableHandle { // Workers don't have an API to cancel sent "executeAfter" block, but we are trying // to control the damage and reduce reachable objects by nulling out `block` // that may retain a lot of references, and leaving only an empty shell after a timely disposal