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