• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
<lambda>null2  * Copyright 2016-2020 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  *
46  * A failure of a child does not cause this scope to fail and does not affect its other children,
47  * so a custom policy for handling failures of its children can be implemented. See [SupervisorJob] for details.
48  * A failure of the scope itself (exception thrown in the [block] or cancellation) fails the scope with all its children,
49  * but does not cancel parent job.
50  */
51 public suspend fun <R> supervisorScope(block: suspend CoroutineScope.() -> R): R {
52     contract {
53         callsInPlace(block, InvocationKind.EXACTLY_ONCE)
54     }
55     return suspendCoroutineUninterceptedOrReturn { uCont ->
56         val coroutine = SupervisorCoroutine(uCont.context, uCont)
57         coroutine.startUndispatchedOrReturn(coroutine, block)
58     }
59 }
60 
61 private class SupervisorJobImpl(parent: Job?) : JobImpl(parent) {
childCancellednull62     override fun childCancelled(cause: Throwable): Boolean = false
63 }
64 
65 private class SupervisorCoroutine<in T>(
66     context: CoroutineContext,
67     uCont: Continuation<T>
68 ) : ScopeCoroutine<T>(context, uCont) {
69     override fun childCancelled(cause: Throwable): Boolean = false
70 }
71