Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Mark the coroutine started with
UNDISPATCHED
as running (#4077)
Fixes #4058 Additional small fix: the coroutine context injected by `probeCoroutineCreated` is used for `CoroutineStart.UNDISPATCHED` even before the first suspension.
- Loading branch information
1 parent
6a4e83d
commit 20bf726
Showing
7 changed files
with
63 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,30 @@ | ||
package kotlinx.coroutines | ||
|
||
import kotlinx.coroutines.intrinsics.* | ||
import kotlinx.coroutines.internal.probeCoroutineCreated | ||
import kotlinx.coroutines.internal.probeCoroutineResumed | ||
import kotlin.coroutines.* | ||
import kotlin.coroutines.intrinsics.* | ||
|
||
suspend fun <T> withEmptyContext(block: suspend () -> T): T = suspendCoroutine { cont -> | ||
block.startCoroutineUnintercepted(Continuation(EmptyCoroutineContext) { cont.resumeWith(it) }) | ||
} | ||
|
||
/** | ||
* Use this function to restart a coroutine directly from inside of [suspendCoroutine], | ||
* when the code is already in the context of this coroutine. | ||
* It does not use [ContinuationInterceptor] and does not update the context of the current thread. | ||
*/ | ||
fun <T> (suspend () -> T).startCoroutineUnintercepted(completion: Continuation<T>) { | ||
val actualCompletion = probeCoroutineCreated(completion) | ||
val value = try { | ||
probeCoroutineResumed(actualCompletion) | ||
startCoroutineUninterceptedOrReturn(actualCompletion) | ||
} catch (e: Throwable) { | ||
actualCompletion.resumeWithException(e) | ||
return | ||
} | ||
if (value !== COROUTINE_SUSPENDED) { | ||
@Suppress("UNCHECKED_CAST") | ||
actualCompletion.resume(value as T) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters