Repository: Kotlin/kotlinx.coroutines
File: kotlinx-coroutines-core/jvm/src/ThreadContextElement.kt (Kotlin)

Code before:
 * `Thread`.
 */
@DelicateCoroutinesApi
@ExperimentalCoroutinesApi
public interface CopyableThreadContextElement<S> : ThreadContextElement<S> {

    /**
     * Returns a [CopyableThreadContextElement] to replace `this` `CopyableThreadContextElement` in the child
     * coroutine's context that is under construction if the child coroutine's context does not contain
     * an element with the same [key].
     *
     * This function is called on the element each time a new coroutine inherits a context containing it,
     * and the returned value is folded into the context given to the child.
     *
     * Since this method is called whenever a new coroutine is launched in a context containing this
     * [CopyableThreadContextElement], implementations are performance-sensitive.
     */
    public fun copyForChild(): CopyableThreadContextElement<S>

    /**
     * Returns a [CopyableThreadContextElement] to replace `this` `CopyableThreadContextElement` in the child
     * coroutine's context when the child coroutine's context contains an element with the same [key] as the
     * current one.
     *
     * This function is called on current element, supplied with an element retrieved from child's
     * coroutine context by the current [key].
     */
    public fun mergeForChild(overwritingElement: CoroutineContext.Element): CoroutineContext
}

/**
 * Wraps [ThreadLocal] into [ThreadContextElement]. The resulting [ThreadContextElement]
 * maintains the given [value] of the given [ThreadLocal] for coroutine regardless of the actual thread its is resumed on.
 * By default [ThreadLocal.get] is used as a value for the thread-local variable, but it can be overridden with [value] parameter.
 * Beware that context element **does not track** modifications of the thread-local and accessing thread-local from coroutine
 * without the corresponding context element returns **undefined** value. See the examples for a detailed description.
 *
 *
 * Example usage:
 * ```
 * val myThreadLocal = ThreadLocal<String?>()
 * ...
 * println(myThreadLocal.get()) // Prints "null"
 * launch(Dispatchers.Default + myThreadLocal.asContextElement(value = "foo")) {
 *   println(myThreadLocal.get()) // Prints "foo"
 *   withContext(Dispatchers.Main) {
 *     println(myThreadLocal.get()) // Prints "foo", but it's on UI thread
 *   }
 * }
 * println(myThreadLocal.get()) // Prints "null"
 * ```

Review comment (suggestion):
```suggestion
     * This method is invoked on the original element, accepting as the parameter
     * the element that is supposed to overwrite it.
```
I find the word "current" unclear in this case. Highlighting the "original/overwriting" relationship between the elements clears things up, I think.

"The child's coroutine context" doesn't seem correct: we're in *the process* of creating the child's coroutine context. The overwriting element is from the "appending portion of the child's coroutine context", but this looks confusing as well.

Code after:
 * ```
 *
 * A coroutine using this mechanism can safely call Java code that assumes the corresponding thread local element's
 * value is installed into the target thread local.
 */
@DelicateCoroutinesApi
@ExperimentalCoroutinesApi
public interface CopyableThreadContextElement<S> : ThreadContextElement<S> {

    /**
     * Returns a [CopyableThreadContextElement] to replace `this` `CopyableThreadContextElement` in the child
     * coroutine's context that is under construction if the added context does not contain an element with the same [key].
     *
     * This function is called on the element each time a new coroutine inherits a context containing it,
     * and the returned value is folded into the context given to the child.
     *
     * Since this method is called whenever a new coroutine is launched in a context containing this
     * [CopyableThreadContextElement], implementations are performance-sensitive.
     */
    public fun copyForChild(): CopyableThreadContextElement<S>

    /**
     * Returns a [CopyableThreadContextElement] to replace `this` `CopyableThreadContextElement` in the child
     * coroutine's context that is under construction if the added context does contain an element with the same [key].
     *
     * This method is invoked on the original element, accepting as the parameter
     * the element that is supposed to overwrite it.
     */
    public fun mergeForChild(overwritingElement: CoroutineContext.Element): CoroutineContext
}

/**
 * Wraps [ThreadLocal] into [ThreadContextElement]. The resulting [ThreadContextElement]
 * maintains the given [value] of the given [ThreadLocal] for coroutine regardless of the actual thread its is resumed on.
 * By default [ThreadLocal.get] is used as a value for the thread-local variable, but it can be overridden with [value] parameter.
 * Beware that context element **does not track** modifications of the thread-local and accessing thread-local from coroutine
 * without the corresponding context element returns **undefined** value. See the examples for a detailed description.
 *
 *
 * Example usage:
 * ```
 * val myThreadLocal = ThreadLocal<String?>()
 * ...
 * println(myThreadLocal.get()) // Prints "null"
 * launch(Dispatchers.Default + myThreadLocal.asContextElement(value = "foo")) {
 *   println(myThreadLocal.get()) // Prints "foo"
 *   withContext(Dispatchers.Main) {
 *     println(myThreadLocal.get()) // Prints "foo", but it's on UI thread
 *   }
 * }
 * println(myThreadLocal.get()) // Prints "null"