• 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 `null`.
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 parent: Job?
38         get() = null
39 
40     /**
41      * Always returns `true`.
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 isActive: Boolean
46         get() = true
47 
48     /**
49      * Always returns `false`.
50      * @suppress **This an internal API and should not be used from general code.**
51      */
52     @Deprecated(level = DeprecationLevel.WARNING, message = message)
53     override val isCompleted: Boolean get() = false
54 
55     /**
56      * Always returns `false`.
57      * @suppress **This an internal API and should not be used from general code.**
58      */
59     @Deprecated(level = DeprecationLevel.WARNING, message = message)
60     override val isCancelled: Boolean get() = false
61 
62     /**
63      * Always returns `false`.
64      * @suppress **This an internal API and should not be used from general code.**
65      */
66     @Deprecated(level = DeprecationLevel.WARNING, message = message)
startnull67     override fun start(): Boolean = false
68 
69     /**
70      * Always throws [UnsupportedOperationException].
71      * @suppress **This an internal API and should not be used from general code.**
72      */
73     @Deprecated(level = DeprecationLevel.WARNING, message = message)
74     override suspend fun join() {
75         throw UnsupportedOperationException("This job is always active")
76     }
77 
78     /**
79      * Always throws [UnsupportedOperationException].
80      * @suppress **This an internal API and should not be used from general code.**
81      */
82     @Deprecated(level = DeprecationLevel.WARNING, message = message)
83     override val onJoin: SelectClause0
84         get() = throw UnsupportedOperationException("This job is always active")
85 
86     /**
87      * Always throws [IllegalStateException].
88      * @suppress **This an internal API and should not be used from general code.**
89      */
90     @Deprecated(level = DeprecationLevel.WARNING, message = message)
getCancellationExceptionnull91     override fun getCancellationException(): CancellationException = throw IllegalStateException("This job is always active")
92 
93     /**
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(handler: CompletionHandler): DisposableHandle =
98         NonDisposableHandle
99 
100     /**
101      * Always returns no-op handle.
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 invokeOnCompletion(onCancelling: Boolean, invokeImmediately: Boolean, handler: CompletionHandler): DisposableHandle =
106         NonDisposableHandle
107 
108     /**
109      * Does nothing.
110      * @suppress **This an internal API and should not be used from general code.**
111      */
112     @Deprecated(level = DeprecationLevel.WARNING, message = message)
113     override fun cancel(cause: CancellationException?) {}
114 
115     /**
116      * Always returns `false`.
117      * @suppress This method has bad semantics when cause is not a [CancellationException]. Use [cancel].
118      */
119     @Deprecated(level = DeprecationLevel.HIDDEN, message = "Since 1.2.0, binary compatibility with versions <= 1.1.x")
cancelnull120     override fun cancel(cause: Throwable?): Boolean = false // never handles exceptions
121 
122     /**
123      * Always returns [emptySequence].
124      * @suppress **This an internal API and should not be used from general code.**
125      */
126     @Deprecated(level = DeprecationLevel.WARNING, message = message)
127     override val children: Sequence<Job>
128         get() = emptySequence()
129 
130     /**
131      * Always returns [NonDisposableHandle] and does not do anything.
132      * @suppress **This an internal API and should not be used from general code.**
133      */
134     @Deprecated(level = DeprecationLevel.WARNING, message = message)
135     override fun attachChild(child: ChildJob): ChildHandle = NonDisposableHandle
136 
137     /** @suppress */
138     override fun toString(): String {
139         return "NonCancellable"
140     }
141 }
142