• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
3  */
4 @file:Suppress("DEPRECATION_ERROR")
5 
6 package kotlinx.coroutines
7 
8 import kotlinx.coroutines.selects.*
9 import kotlin.coroutines.*
10 
11 /**
12  * A non-cancelable job that is always [active][Job.isActive]. It is designed for [withContext] function
13  * to prevent cancellation of code blocks that need to be executed without cancellation.
14  *
15  * Use it like this:
16  * ```
17  * withContext(NonCancellable) {
18  *     // this code will not be cancelled
19  * }
20  * ```
21  *
22  * **WARNING**: This object is not designed to be used with [launch], [async], and other coroutine builders.
23  * if you write `launch(NonCancellable) { ... }` then not only the newly launched job will not be cancelled
24  * when the parent is cancelled, the whole parent-child relation between parent and child is severed.
25  * The parent will not wait for the child's completion, nor will be cancelled when the child crashed.
26  */
27 @Suppress("DeprecatedCallableAddReplaceWith")
28 public object NonCancellable : AbstractCoroutineContextElement(Job), Job {
29 
30     private const val message = "NonCancellable can be used only as an argument for 'withContext', direct usages of its API are prohibited"
31 
32     /**
33      * Always returns `true`.
34      * @suppress **This an internal API and should not be used from general code.**
35      */
36     @Deprecated(level = DeprecationLevel.WARNING, message = message)
37     override val isActive: Boolean
38         get() = true
39 
40     /**
41      * Always returns `false`.
42      * @suppress **This an internal API and should not be used from general code.**
43      */
44     @Deprecated(level = DeprecationLevel.WARNING, message = message)
45     override val isCompleted: Boolean get() = false
46 
47     /**
48      * Always returns `false`.
49      * @suppress **This an internal API and should not be used from general code.**
50      */
51     @Deprecated(level = DeprecationLevel.WARNING, message = message)
52     override val isCancelled: Boolean get() = false
53 
54     /**
55      * Always returns `false`.
56      * @suppress **This an internal API and should not be used from general code.**
57      */
58     @Deprecated(level = DeprecationLevel.WARNING, message = message)
startnull59     override fun start(): Boolean = false
60 
61     /**
62      * Always throws [UnsupportedOperationException].
63      * @suppress **This an internal API and should not be used from general code.**
64      */
65     @Deprecated(level = DeprecationLevel.WARNING, message = message)
66     override suspend fun join() {
67         throw UnsupportedOperationException("This job is always active")
68     }
69 
70     /**
71      * Always throws [UnsupportedOperationException].
72      * @suppress **This an internal API and should not be used from general code.**
73      */
74     @Deprecated(level = DeprecationLevel.WARNING, message = message)
75     override val onJoin: SelectClause0
76         get() = throw UnsupportedOperationException("This job is always active")
77 
78     /**
79      * Always throws [IllegalStateException].
80      * @suppress **This an internal API and should not be used from general code.**
81      */
82     @Deprecated(level = DeprecationLevel.WARNING, message = message)
getCancellationExceptionnull83     override fun getCancellationException(): CancellationException = throw IllegalStateException("This job is always active")
84 
85     /**
86      * @suppress **This an internal API and should not be used from general code.**
87      */
88     @Deprecated(level = DeprecationLevel.WARNING, message = message)
89     override fun invokeOnCompletion(handler: CompletionHandler): DisposableHandle =
90         NonDisposableHandle
91 
92     /**
93      * Always returns no-op handle.
94      * @suppress **This an internal API and should not be used from general code.**
95      */
96     @Deprecated(level = DeprecationLevel.WARNING, message = message)
97     override fun invokeOnCompletion(onCancelling: Boolean, invokeImmediately: Boolean, handler: CompletionHandler): DisposableHandle =
98         NonDisposableHandle
99 
100     /**
101      * Does nothing.
102      * @suppress **This an internal API and should not be used from general code.**
103      */
104     @Deprecated(level = DeprecationLevel.WARNING, message = message)
105     override fun cancel(cause: CancellationException?) {}
106 
107     /**
108      * Always returns `false`.
109      * @suppress This method has bad semantics when cause is not a [CancellationException]. Use [cancel].
110      */
111     @Deprecated(level = DeprecationLevel.HIDDEN, message = "Since 1.2.0, binary compatibility with versions <= 1.1.x")
cancelnull112     override fun cancel(cause: Throwable?): Boolean = false // never handles exceptions
113 
114     /**
115      * Always returns [emptySequence].
116      * @suppress **This an internal API and should not be used from general code.**
117      */
118     @Deprecated(level = DeprecationLevel.WARNING, message = message)
119     override val children: Sequence<Job>
120         get() = emptySequence()
121 
122     /**
123      * Always returns [NonDisposableHandle] and does not do anything.
124      * @suppress **This an internal API and should not be used from general code.**
125      */
126     @Deprecated(level = DeprecationLevel.WARNING, message = message)
127     override fun attachChild(child: ChildJob): ChildHandle = NonDisposableHandle
128 
129     /** @suppress */
130     override fun toString(): String {
131         return "NonCancellable"
132     }
133 }
134