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