Skip to content

Commit

Permalink
Fix FlushCoroutineDispatcher.scheduleResumeAfterDelay to correctly ca…
Browse files Browse the repository at this point in the history
…ncel the delayed task when the continuation is cancelled. (#596)
  • Loading branch information
m-sasha committed Jul 3, 2023
1 parent 6033a53 commit 53f869f
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -100,16 +100,22 @@ internal class FlushCoroutineDispatcher(
synchronized(tasksLock) {
delayedTasks.add(block)
}
scope.launch {
kotlinx.coroutines.delay(timeMillis)
performRun {
val isTaskAlive = synchronized(tasksLock) {
delayedTasks.remove(block)
}
if (isTaskAlive) {
block.run()
val job = scope.launch {
try{
kotlinx.coroutines.delay(timeMillis)
} finally {
performRun {
val isTaskAlive = synchronized(tasksLock) {
delayedTasks.remove(block)
}
if (isTaskAlive) {
block.run()
}
}
}
}
continuation.invokeOnCancellation {
job.cancel()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,13 @@

package androidx.compose.ui.platform

import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
import kotlinx.coroutines.test.runTest
import kotlinx.coroutines.yield
import kotlin.random.Random
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlinx.coroutines.withContext
import kotlin.test.assertTrue
import kotlinx.coroutines.*

@OptIn(ExperimentalCoroutinesApi::class)
class FlushCoroutineDispatcherTest {
Expand Down Expand Up @@ -106,4 +103,19 @@ class FlushCoroutineDispatcherTest {
assertEquals((0 until 10000).toList(), actualNumbers)
assertFalse(dispatcher.hasTasks())
}

@Test
fun delayed_tasks_are_cancelled() = runTest {
val coroutineScope = CoroutineScope(Dispatchers.Unconfined)
val dispatcher = FlushCoroutineDispatcher(coroutineScope)
val job = launch(dispatcher){
delay(Long.MAX_VALUE/2)
}
assertTrue(dispatcher.hasTasks())
job.cancel()
assertTrue(
!dispatcher.hasTasks(),
"FlushCoroutineDispatcher has a delayed task that has been cancelled"
)
}
}

0 comments on commit 53f869f

Please sign in to comment.