xref: /aosp_15_r20/external/kotlinx.coroutines/kotlinx-coroutines-core/concurrent/src/channels/Channels.kt (revision 7a7160fed73afa6648ef8aa100d4a336fe921d9a)
1 @file:JvmMultifileClass
2 @file:JvmName("ChannelsKt")
3 
4 package kotlinx.coroutines.channels
5 
6 import kotlinx.coroutines.*
7 import kotlin.jvm.*
8 
9 /**
10  * Adds [element] to this channel, **blocking** the caller while this channel is full,
11  * and returning either [successful][ChannelResult.isSuccess] result when the element was added, or
12  * failed result representing closed channel with a corresponding exception.
13  *
14  * This is a way to call [Channel.send] method in a safe manner inside a blocking code using [runBlocking] and catching,
15  * so this function should not be used from coroutine.
16  *
17  * Example of usage:
18  *
19  * ```
20  * // From callback API
21  * channel.trySendBlocking(element)
22  *     .onSuccess { /* request next element or debug log */ }
23  *     .onFailure { t: Throwable? -> /* throw or log */ }
24  * ```
25  *
26  * For this operation it is guaranteed that [failure][ChannelResult.failed] always contains an exception in it.
27  *
28  * @throws `InterruptedException` on JVM if the current thread is interrupted during the blocking send operation.
29  */
trySendBlockingnull30 public fun <E> SendChannel<E>.trySendBlocking(element: E): ChannelResult<Unit> {
31     /*
32      * Sent successfully -- bail out.
33      * But failure may indicate either that the channel is full or that
34      * it is close. Go to slow path on failure to simplify the successful path and
35      * to materialize default exception.
36      */
37     trySend(element).onSuccess { return ChannelResult.success(Unit) }
38     return runBlocking {
39         val r = runCatching { send(element) }
40         if (r.isSuccess) ChannelResult.success(Unit)
41         else ChannelResult.closed(r.exceptionOrNull())
42     }
43 }
44 
45 /** @suppress */
46 @Deprecated(
47     level = DeprecationLevel.HIDDEN,
48     message = "Deprecated in the favour of 'trySendBlocking'. " +
49         "Consider handling the result of 'trySendBlocking' explicitly and rethrow exception if necessary",
50     replaceWith = ReplaceWith("trySendBlocking(element)")
51 ) // WARNING in 1.5.0, ERROR in 1.6.0
sendBlockingnull52 public fun <E> SendChannel<E>.sendBlocking(element: E) {
53     // fast path
54     if (trySend(element).isSuccess)
55         return
56     // slow path
57     runBlocking {
58         send(element)
59     }
60 }
61