add CoroutineSuspender.isPaused

GitOrigin-RevId: 2fb484bf129cca5640aa0bb6629f8effd876b8fb
This commit is contained in:
Daniil Ovchinnikov
2023-03-01 17:31:34 +00:00
committed by intellij-monorepo-bot
parent 09fa520e3f
commit f0e7e884d9
2 changed files with 9 additions and 0 deletions
@@ -40,6 +40,8 @@ fun coroutineSuspender(active: Boolean = true): CoroutineSuspender = CoroutineSu
@ApiStatus.NonExtendable
interface CoroutineSuspender : CoroutineContext {
fun isPaused(): Boolean
fun pause()
fun resume()
@@ -68,6 +70,10 @@ internal class CoroutineSuspenderElement(active: Boolean)
if (active) CoroutineSuspenderState.Active else EMPTY_PAUSED_STATE
)
override fun isPaused(): Boolean {
return myState.get() is CoroutineSuspenderState.Paused
}
override fun pause() {
myState.compareAndSet(CoroutineSuspenderState.Active, EMPTY_PAUSED_STATE)
}
@@ -13,6 +13,7 @@ class CoroutineSuspenderTest : LightPlatformTestCase() {
val count = 10
val started = Semaphore(count, count)
val suspender = coroutineSuspender(false)
assertTrue(suspender.isPaused())
val job = launch(Dispatchers.Default + suspender) {
repeat(count) {
launch {
@@ -33,6 +34,7 @@ class CoroutineSuspenderTest : LightPlatformTestCase() {
val started = Semaphore(count, count)
val paused = Semaphore(count, count)
val suspender = coroutineSuspender()
assertFalse(suspender.isPaused())
val result = async(Dispatchers.Default + suspender) {
(1..count).map {
async { // coroutine context (including CoroutineSuspender) is inherited
@@ -46,6 +48,7 @@ class CoroutineSuspenderTest : LightPlatformTestCase() {
}
started.timeoutAcquire() // all coroutines are started
suspender.pause() // pause suspender before next checkCanceled
assertTrue(suspender.isPaused())
repeat(count) {
paused.release() // let coroutines pause in next checkCanceled
}