• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3  */
4 @file:OptIn(ExperimentalContracts::class)
5 @file:Suppress("DEPRECATION_ERROR")
6 
7 package kotlinx.coroutines
8 
9 import kotlinx.coroutines.internal.*
10 import kotlinx.coroutines.intrinsics.*
11 import kotlin.contracts.*
12 import kotlin.coroutines.*
13 import kotlin.coroutines.intrinsics.*
14 import kotlin.jvm.*
15 
16 /**
17  * Creates a _supervisor_ job object in an active state.
18  * Children of a supervisor job can fail independently of each other.
19  *
20  * A failure or cancellation of a child does not cause the supervisor job to fail and does not affect its other children,
21  * so a supervisor can implement a custom policy for handling failures of its children:
22  *
23  * * A failure of a child job that was created using [launch][CoroutineScope.launch] can be handled via [CoroutineExceptionHandler] in the context.
24  * * A failure of a child job that was created using [async][CoroutineScope.async] can be handled via [Deferred.await] on the resulting deferred value.
25  *
26  * If [parent] job is specified, then this supervisor job becomes a child job of its parent and is cancelled when its
27  * parent fails or is cancelled. All this supervisor's children are cancelled in this case, too. The invocation of
28  * [cancel][Job.cancel] with exception (other than [CancellationException]) on this supervisor job also cancels parent.
29  *
30  * @param parent an optional parent job.
31  */
32 @Suppress("FunctionName")
33 public fun SupervisorJob(parent: Job? = null) : CompletableJob = SupervisorJobImpl(parent)
34 
35 /** @suppress Binary compatibility only */
36 @Suppress("FunctionName")
37 @Deprecated(level = DeprecationLevel.HIDDEN, message = "Since 1.2.0, binary compatibility with versions <= 1.1.x")
38 @JvmName("SupervisorJob")
39 public fun SupervisorJob0(parent: Job? = null) : Job = SupervisorJob(parent)
40 
41 /**
42  * Creates a [CoroutineScope] with [SupervisorJob] and calls the specified suspend block with this scope.
43  * The provided scope inherits its [coroutineContext][CoroutineScope.coroutineContext] from the outer scope, but overrides
44  * context's [Job] with [SupervisorJob].
45  * This function returns as soon as the given block and all its child coroutines are completed.
46  *
47  * Unlike [coroutineScope], a failure of a child does not cause this scope to fail and does not affect its other children,
48  * so a custom policy for handling failures of its children can be implemented. See [SupervisorJob] for additional details.
49  * A failure of the scope itself (exception thrown in the [block] or external cancellation) fails the scope with all its children,
50  * but does not cancel parent job.
51  *
52  * The method may throw a [CancellationException] if the current job was cancelled externally,
53  * or rethrow an exception thrown by the given [block].
54  */
55 public suspend fun <R> supervisorScope(block: suspend CoroutineScope.() -> R): R {
56     contract {
57         callsInPlace(block, InvocationKind.EXACTLY_ONCE)
58     }
59     return suspendCoroutineUninterceptedOrReturn { uCont ->
60         val coroutine = SupervisorCoroutine(uCont.context, uCont)
61         coroutine.startUndispatchedOrReturn(coroutine, block)
62     }
63 }
64 
65 private class SupervisorJobImpl(parent: Job?) : JobImpl(parent) {
childCancellednull66     override fun childCancelled(cause: Throwable): Boolean = false
67 }
68 
69 private class SupervisorCoroutine<in T>(
70     context: CoroutineContext,
71     uCont: Continuation<T>
72 ) : ScopeCoroutine<T>(context, uCont) {
73     override fun childCancelled(cause: Throwable): Boolean = false
74 }
75