Further design improvements for coroutines 1.3 APIs
* Documentation improvements and clarification * Dropped legacy intrinsic functions * Remove context parameter default from Continuation builder function
This commit is contained in:
committed by
Denis Zharkov
parent
719d45510a
commit
0370fac0b6
@@ -32,19 +32,6 @@ public expect inline fun <R, T> (suspend R.() -> T).startCoroutineUninterceptedO
|
||||
completion: Continuation<T>
|
||||
): Any?
|
||||
|
||||
@SinceKotlin("1.3")
|
||||
// todo: Drop this function
|
||||
public expect fun <T> (suspend () -> T).createCoroutineUnchecked(
|
||||
completion: Continuation<T>
|
||||
): Continuation<Unit>
|
||||
|
||||
@SinceKotlin("1.3")
|
||||
// todo: Drop this function
|
||||
public expect fun <R, T> (suspend R.() -> T).createCoroutineUnchecked(
|
||||
receiver: R,
|
||||
completion: Continuation<T>
|
||||
): Continuation<Unit>
|
||||
|
||||
@SinceKotlin("1.3")
|
||||
public expect fun <T> (suspend () -> T).createCoroutineUnintercepted(
|
||||
completion: Continuation<T>
|
||||
|
||||
@@ -54,41 +54,6 @@ public actual inline fun <R, T> (suspend R.() -> T).startCoroutineUninterceptedO
|
||||
|
||||
// JVM declarations
|
||||
|
||||
/**
|
||||
* Creates a coroutine without receiver and with result type [T].
|
||||
* This function creates a new, fresh instance of suspendable computation every time it is invoked.
|
||||
*
|
||||
* To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance.
|
||||
* The [completion] continuation is invoked when coroutine completes with result or exception.
|
||||
*
|
||||
* This function is _unchecked_. Repeated invocation of any resume function on the resulting continuation corrupts the
|
||||
* state machine of the coroutine and may result in arbitrary behaviour or exception.
|
||||
*/
|
||||
@SinceKotlin("1.3")
|
||||
// todo: Drop this function
|
||||
public actual fun <T> (suspend () -> T).createCoroutineUnchecked(
|
||||
completion: Continuation<T>
|
||||
): Continuation<Unit> =
|
||||
createCoroutineUnintercepted(completion).intercepted()
|
||||
|
||||
/**
|
||||
* Creates a coroutine with receiver type [R] and result type [T].
|
||||
* This function creates a new, fresh instance of suspendable computation every time it is invoked.
|
||||
*
|
||||
* To start executing the created coroutine, invoke `resume(Unit)` on the returned [Continuation] instance.
|
||||
* The [completion] continuation is invoked when coroutine completes with result or exception.
|
||||
*
|
||||
* This function is _unchecked_. Repeated invocation of any resume function on the resulting continuation corrupts the
|
||||
* state machine of the coroutine and may result in arbitrary behaviour or exception.
|
||||
*/
|
||||
@SinceKotlin("1.3")
|
||||
// todo: Drop this function
|
||||
public actual fun <R, T> (suspend R.() -> T).createCoroutineUnchecked(
|
||||
receiver: R,
|
||||
completion: Continuation<T>
|
||||
): Continuation<Unit> =
|
||||
createCoroutineUnintercepted(receiver, completion).intercepted()
|
||||
|
||||
/**
|
||||
* Creates unintercepted coroutine without receiver and with result type [T].
|
||||
* This function creates a new, fresh instance of suspendable computation every time it is invoked.
|
||||
@@ -97,10 +62,15 @@ public actual fun <R, T> (suspend R.() -> T).createCoroutineUnchecked(
|
||||
* The [completion] continuation is invoked when coroutine completes with result or exception.
|
||||
*
|
||||
* This function returns unintercepted continuation.
|
||||
* Invocation of `resume(Unit)` starts coroutine directly in the invoker's thread without going through the
|
||||
* Invocation of `resume(Unit)` starts coroutine immediately in the invoker's call stack without going through the
|
||||
* [ContinuationInterceptor] that might be present in the completion's [CoroutineContext].
|
||||
* It is invoker's responsibility to ensure that the proper invocation context is established.
|
||||
* Note that [completion] of this function may get invoked in an arbitrary context.
|
||||
*
|
||||
* [Continuation.intercepted] can be used to acquire the intercepted continuation.
|
||||
* Invocation of `resume(Unit)` on intercepted continuation guarantees that execution of
|
||||
* both the coroutine and [completion] happens in the invocation context established by
|
||||
* [ContinuationInterceptor].
|
||||
*
|
||||
* Repeated invocation of any resume function on the resulting continuation corrupts the
|
||||
* state machine of the coroutine and may result in arbitrary behaviour or exception.
|
||||
@@ -124,10 +94,15 @@ public actual fun <T> (suspend () -> T).createCoroutineUnintercepted(
|
||||
* The [completion] continuation is invoked when coroutine completes with result or exception.
|
||||
*
|
||||
* This function returns unintercepted continuation.
|
||||
* Invocation of `resume(Unit)` starts coroutine directly in the invoker's thread without going through the
|
||||
* Invocation of `resume(Unit)` starts coroutine immediately in the invoker's call stack without going through the
|
||||
* [ContinuationInterceptor] that might be present in the completion's [CoroutineContext].
|
||||
* It is invoker's responsibility to ensure that the proper invocation context is established.
|
||||
* Note that [completion] of this function may get invoked in an arbitrary context.
|
||||
*
|
||||
* [Continuation.intercepted] can be used to acquire the intercepted continuation.
|
||||
* Invocation of `resume(Unit)` on intercepted continuation guarantees that execution of
|
||||
* both the coroutine and [completion] happens in the invocation context established by
|
||||
* [ContinuationInterceptor].
|
||||
*
|
||||
* Repeated invocation of any resume function on the resulting continuation corrupts the
|
||||
* state machine of the coroutine and may result in arbitrary behaviour or exception.
|
||||
@@ -147,6 +122,12 @@ public actual fun <R, T> (suspend R.() -> T).createCoroutineUnintercepted(
|
||||
|
||||
/**
|
||||
* Intercepts this continuation with [ContinuationInterceptor].
|
||||
*
|
||||
* This function shall be used on the immediate result of [createCoroutineUnintercepted] or [suspendCoroutineUninterceptedOrReturn],
|
||||
* in which case it checks for [ContinuationInterceptor] in the continuation's [context][Continuation.context],
|
||||
* invokes [ContinuationInterceptor.interceptContinuation], caches and returns result.
|
||||
*
|
||||
* If this function is invoked on other [Continuation] instances it returns `this` continuation unchanged.
|
||||
*/
|
||||
@SinceKotlin("1.3")
|
||||
public actual fun <T> Continuation<T>.intercepted(): Continuation<T> =
|
||||
|
||||
@@ -59,7 +59,7 @@ public annotation class RestrictsSuspension
|
||||
*/
|
||||
@SinceKotlin("1.3")
|
||||
@InlineOnly public inline fun <T> Continuation(
|
||||
context: CoroutineContext = EmptyCoroutineContext,
|
||||
context: CoroutineContext,
|
||||
crossinline resumeWith: (SuccessOrFailure<T>) -> Unit
|
||||
): Continuation<T> =
|
||||
object : Continuation<T> {
|
||||
@@ -146,12 +146,7 @@ public suspend inline fun <T> suspendCoroutine(crossinline block: (Continuation<
|
||||
}
|
||||
|
||||
/**
|
||||
* Continuation context of current coroutine.
|
||||
*
|
||||
* This allows the user code to not pass an extra [CoroutineContext] parameter in basic coroutine builders
|
||||
* like [launch](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/launch.html)
|
||||
* and [async](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.experimental/async.html),
|
||||
* but still provide easy access to coroutine context.
|
||||
* Returns context of the current coroutine.
|
||||
*/
|
||||
@SinceKotlin("1.3")
|
||||
@Suppress("WRONG_MODIFIER_TARGET")
|
||||
|
||||
@@ -12,30 +12,6 @@ package kotlin.coroutines.intrinsics
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.internal.InlineOnly
|
||||
|
||||
/**
|
||||
* Obtains the current continuation instance inside suspend functions and either suspends
|
||||
* currently running coroutine or returns result immediately without suspension.
|
||||
*
|
||||
* If the [block] returns the special [COROUTINE_SUSPENDED] value, it means that suspend function did suspend the execution and will
|
||||
* not return any result immediately. In this case, the [Continuation] provided to the [block] shall be invoked at some moment in the
|
||||
* future when the result becomes available to resume the computation.
|
||||
*
|
||||
* Otherwise, the return value of the [block] must have a type assignable to [T] and represents the result of this suspend function.
|
||||
* It means that the execution was not suspended and the [Continuation] provided to the [block] shall not be invoked.
|
||||
* As the result type of the [block] is declared as `Any?` and cannot be correctly type-checked,
|
||||
* its proper return type remains on the conscience of the suspend function's author.
|
||||
*
|
||||
* Note that it is not recommended to call either [Continuation.resume] nor [Continuation.resumeWithException] functions synchronously
|
||||
* in the same stackframe where suspension function is run. Use [suspendCoroutine] as a safer way to obtain current
|
||||
* continuation instance.
|
||||
*/
|
||||
@SinceKotlin("1.3")
|
||||
@InlineOnly
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
// todo: Drop this function
|
||||
public suspend inline fun <T> suspendCoroutineOrReturn(crossinline block: (Continuation<T>) -> Any?): T =
|
||||
suspendCoroutineUninterceptedOrReturn { cont -> block(cont.intercepted()) }
|
||||
|
||||
/**
|
||||
* Obtains the current continuation instance inside suspend functions and either suspends
|
||||
* currently running coroutine or returns result immediately without suspension.
|
||||
|
||||
Reference in New Issue
Block a user