Skip to content

Commit 7757b06

Browse files
committed
~documentation tweaks
1 parent 8563d46 commit 7757b06

File tree

3 files changed

+21
-9
lines changed

3 files changed

+21
-9
lines changed

kotlinx-coroutines-core/common/src/Builders.common.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ public suspend fun <T> withContext(
148148
return suspendCoroutineUninterceptedOrReturn sc@ { uCont ->
149149
// compute new context
150150
val oldContext = uCont.context
151+
// Copy CopyableThreadContextElement if necessary
151152
val newContext = oldContext.newCoroutineContext(context)
152153
// always check for cancellation of new context
153154
newContext.ensureActive()

kotlinx-coroutines-core/common/src/CoroutineContext.common.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,16 @@ import kotlin.coroutines.*
88

99
/**
1010
* Creates a context for the new coroutine. It installs [Dispatchers.Default] when no other dispatcher or
11-
* [ContinuationInterceptor] is specified, and adds optional support for debugging facilities (when turned on).
11+
* [ContinuationInterceptor] is specified, and adds optional support for debugging facilities (when turned on)
12+
* and copyable thread local facilities on JVM.
1213
*/
1314
public expect fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext
1415

16+
/**
17+
* Creates context for coroutine builder functions that do not launch a new coroutine, namely [withContext].
18+
* @suppress
19+
*/
20+
@InternalCoroutinesApi
1521
public expect fun CoroutineContext.newCoroutineContext(addedContext: CoroutineContext): CoroutineContext
1622

1723
@PublishedApi

kotlinx-coroutines-core/jvm/src/CoroutineContext.kt

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import kotlin.coroutines.jvm.internal.CoroutineStackFrame
1111
/**
1212
* Creates context for the new coroutine. It installs [Dispatchers.Default] when no other dispatcher nor
1313
* [ContinuationInterceptor] is specified, and adds optional support for
14-
* copyable thread context [elements][CopyableThreadContextElement] and debugging facilities (when turned on).
14+
* copyable thread context [elements][CopyableThreadContextElement] and debugging facilities (when turned on).
1515
*
1616
* See [DEBUG_PROPERTY_NAME] for description of debugging facilities on JVM.
1717
*/
@@ -24,26 +24,32 @@ public actual fun CoroutineScope.newCoroutineContext(context: CoroutineContext):
2424
}
2525

2626
/**
27-
* Creates context for coroutine builder functions that do not launch a new coroutine,
28-
* but change current coroutine context, such as [withContext].
27+
* Creates context for coroutine builder functions that do not launch a new coroutine, namely [withContext].
28+
* @suppress
2929
*/
30-
@ExperimentalCoroutinesApi
30+
@InternalCoroutinesApi
3131
public actual fun CoroutineContext.newCoroutineContext(addedContext: CoroutineContext): CoroutineContext {
3232
/*
3333
* Fast-path: we only have to copy/merge if 'addedContext' (which typically has one or two elements)
3434
* contains copyable element.
3535
*/
3636
if (!addedContext.fold(false, hasCopyableElements)) return this + addedContext
37-
// TODO Here addedContext will be re-evaluated, we can fix it later when the design converges to its final form.
3837
return foldCopies(this, addedContext, false)
3938
}
4039

4140
private val hasCopyableElements: (Boolean, CoroutineContext.Element) -> Boolean = { result, it ->
4241
result || it is CopyableThreadContextElement<*>
4342
}
4443

45-
/*
46-
* Folds two contexts if there is need to.
44+
/**
45+
* Folds two contexts properly applying [CopyableThreadContextElement] rules when necessary.
46+
* The rules are the following:
47+
* * If both context do not have CTCE, the sum of two contexts is returned
48+
* * Every CTCE from left-hand side context that does not have matching (by key) element from right-hand side context
49+
* is [copied][CopyableThreadContextElement.copyForChild]
50+
* * Every CTCE from left-hand side context that has matching element in right-hand side context is [merged][CopyableThreadContextElement.mergeForChild]
51+
* * Every CTCE from right-hand side context that hasn't been merged is copied
52+
* * Everything else is added to the resulting context as is.
4753
*/
4854
private fun foldCopies(originalContext: CoroutineContext, appendContext: CoroutineContext, isNewCoroutine: Boolean): CoroutineContext {
4955
// Do we have something to copy left-hand side?
@@ -56,7 +62,6 @@ private fun foldCopies(originalContext: CoroutineContext, appendContext: Corouti
5662
}
5763

5864
var leftoverContext = appendContext
59-
6065
val folded = originalContext.fold<CoroutineContext>(EmptyCoroutineContext) { result, element ->
6166
if (element !is CopyableThreadContextElement<*>) return@fold result + element
6267
// Will this element be overwritten?

0 commit comments

Comments
 (0)