|
| 1 | +package kotlinx.coroutines.experimental.channels |
| 2 | + |
| 3 | +import kotlinx.coroutines.experimental.CancellationException |
| 4 | +import kotlinx.coroutines.experimental.CoroutineScope |
| 5 | +import kotlinx.coroutines.experimental.Job |
| 6 | +import kotlinx.coroutines.experimental.yield |
| 7 | +import java.util.* |
| 8 | + |
| 9 | +/** |
| 10 | + * Sender's interface to [Channel]. |
| 11 | + */ |
| 12 | +public interface SendChannel<in E> { |
| 13 | + /** |
| 14 | + * Returns `true` if this channel was closed by invocation of [close] and thus |
| 15 | + * the [send] attempt will throw [ClosedSendChannelException]. |
| 16 | + */ |
| 17 | + public val isClosedForSend: Boolean |
| 18 | + |
| 19 | + /** |
| 20 | + * Returns `true` if the channel is full (out of capacity) and the [send] attempt will suspend. |
| 21 | + * This function returns `false` for [isClosedForSend] channel. |
| 22 | + */ |
| 23 | + public val isFull: Boolean |
| 24 | + |
| 25 | + /** |
| 26 | + * Adds [element] into to this queue, suspending the caller while this queue [isFull], |
| 27 | + * or throws [ClosedSendChannelException] if the channel [isClosedForSend]. |
| 28 | + * |
| 29 | + * This suspending function is cancellable. If the [Job] of the current coroutine is completed while this |
| 30 | + * function is suspended, this function immediately resumes with [CancellationException]. |
| 31 | + * Cancellation of suspended send is *atomic* -- when this function |
| 32 | + * throws [CancellationException] it means that the [element] was not sent to this channel. |
| 33 | + * |
| 34 | + * Note, that this function does not check for cancellation when it is not suspended. |
| 35 | + * Use [yield] or [CoroutineScope.isActive] to periodically check for cancellation in tight loops if needed. |
| 36 | + */ |
| 37 | + public suspend fun send(element: E) |
| 38 | + |
| 39 | + /** |
| 40 | + * Adds [element] into this queue if it is possible to do so immediately without violating capacity restrictions |
| 41 | + * and returns `true`. Otherwise, it returns `false` immediately |
| 42 | + * or throws [ClosedSendChannelException] if the channel [isClosedForSend]. |
| 43 | + */ |
| 44 | + public fun offer(element: E): Boolean |
| 45 | + |
| 46 | + /** |
| 47 | + * Closes this channel. This is an idempotent operation -- repeated invocations of this function have no effect. |
| 48 | + * Conceptually, its sends a special close token of this channel. Immediately after invocation of this function |
| 49 | + * [isClosedForSend] starts returning `true`. However, [isClosedForReceive][ReceiveChannel.isClosedForReceive] |
| 50 | + * on the side of [ReceiveChannel] starts returning `true` only after all previously sent elements |
| 51 | + * are received. |
| 52 | + */ |
| 53 | + public fun close() |
| 54 | +} |
| 55 | + |
| 56 | +/** |
| 57 | + * Receiver's interface to [Channel]. |
| 58 | + */ |
| 59 | +public interface ReceiveChannel<out E> { |
| 60 | + /** |
| 61 | + * Returns `true` if this channel was closed by invocation of [close][SendChannel.close] on the [SendChannel] |
| 62 | + * side and all previously sent items were already received, so that the [receive] attempt will |
| 63 | + * throw [ClosedReceiveChannelException]. |
| 64 | + */ |
| 65 | + public val isClosedForReceive: Boolean |
| 66 | + |
| 67 | + /** |
| 68 | + * Returns `true` if the channel is empty (contains no elements) and the [receive] attempt will suspend. |
| 69 | + * This function returns `false` for [isClosedForReceive] channel. |
| 70 | + */ |
| 71 | + public val isEmpty: Boolean |
| 72 | + |
| 73 | + /** |
| 74 | + * Retrieves and removes the element from this channel suspending the caller while this channel [isEmpty] |
| 75 | + * or throws [ClosedReceiveChannelException] if the channel [isClosedForReceive]. |
| 76 | + * |
| 77 | + * This suspending function is cancellable. If the [Job] of the current coroutine is completed while this |
| 78 | + * function is suspended, this function immediately resumes with [CancellationException]. |
| 79 | + * Cancellation of suspended receive is *atomic* -- when this function |
| 80 | + * throws [CancellationException] it means that the element was not retrieved from this channel. |
| 81 | + * |
| 82 | + * Note, that this function does not check for cancellation when it is not suspended. |
| 83 | + * Use [yield] or [CoroutineScope.isActive] to periodically check for cancellation in tight loops if needed. |
| 84 | + */ |
| 85 | + public suspend fun receive(): E |
| 86 | + |
| 87 | + /** |
| 88 | + * Retrieves and removes the element from this channel suspending the caller while this channel [isEmpty] |
| 89 | + * or returns `null` if the channel [isClosedForReceive]. |
| 90 | + * |
| 91 | + * This suspending function is cancellable. If the [Job] of the current coroutine is completed while this |
| 92 | + * function is suspended, this function immediately resumes with [CancellationException]. |
| 93 | + * Cancellation of suspended receive is *atomic* -- when this function |
| 94 | + * throws [CancellationException] it means that the element was not retrieved from this channel. |
| 95 | + * |
| 96 | + * Note, that this function does not check for cancellation when it is not suspended. |
| 97 | + * Use [yield] or [CoroutineScope.isActive] to periodically check for cancellation in tight loops if needed. |
| 98 | + */ |
| 99 | + public suspend fun receiveOrNull(): E? |
| 100 | + |
| 101 | + /** |
| 102 | + * Retrieves and removes the head of this queue, or returns `null` if this queue [isEmpty] |
| 103 | + * or [isClosedForReceive]. |
| 104 | + */ |
| 105 | + public fun pool(): E? |
| 106 | + |
| 107 | + /** |
| 108 | + * Returns new iterator to receive elements from this channels using `for` loop. |
| 109 | + */ |
| 110 | + public operator fun iterator(): ChannelIterator<E> |
| 111 | +} |
| 112 | + |
| 113 | +/** |
| 114 | + * Iterator for [ReceiveChannel]. Instances of this interface are *not thread-safe* and shall not be used |
| 115 | + * from concurrent coroutines. |
| 116 | + */ |
| 117 | +public interface ChannelIterator<out E> { |
| 118 | + /** |
| 119 | + * Returns `true` if the channel has more elements suspending the caller while this channel |
| 120 | + * [isEmpty][ReceiveChannel.isEmpty] or `false` [ClosedReceiveChannelException] if the channel |
| 121 | + * [isClosedForReceive][ReceiveChannel.isClosedForReceive]. |
| 122 | + * This function retrieves and removes the element from this channel for the subsequent invocation |
| 123 | + * of [next]. |
| 124 | + * |
| 125 | + * This suspending function is cancellable. If the [Job] of the current coroutine is completed while this |
| 126 | + * function is suspended, this function immediately resumes with [CancellationException]. |
| 127 | + * Cancellation of suspended receive is *atomic* -- when this function |
| 128 | + * throws [CancellationException] it means that the element was not retrieved from this channel. |
| 129 | + * |
| 130 | + * Note, that this function does not check for cancellation when it is not suspended. |
| 131 | + * Use [yield] or [CoroutineScope.isActive] to periodically check for cancellation in tight loops if needed. |
| 132 | + */ |
| 133 | + public suspend operator fun hasNext(): Boolean |
| 134 | + |
| 135 | + /** |
| 136 | + * Retrieves and removes the element from this channel suspending the caller while this channel |
| 137 | + * [isEmpty][ReceiveChannel.isEmpty] or throws [ClosedReceiveChannelException] if the channel |
| 138 | + * [isClosedForReceive][ReceiveChannel.isClosedForReceive]. |
| 139 | + * |
| 140 | + * This suspending function is cancellable. If the [Job] of the current coroutine is completed while this |
| 141 | + * function is suspended, this function immediately resumes with [CancellationException]. |
| 142 | + * Cancellation of suspended receive is *atomic* -- when this function |
| 143 | + * throws [CancellationException] it means that the element was not retrieved from this channel. |
| 144 | + * |
| 145 | + * Note, that this function does not check for cancellation when it is not suspended. |
| 146 | + * Use [yield] or [CoroutineScope.isActive] to periodically check for cancellation in tight loops if needed. |
| 147 | + */ |
| 148 | + public suspend operator fun next(): E |
| 149 | +} |
| 150 | + |
| 151 | +/** |
| 152 | + * Channel is a non-blocking primitive for communication between sender using [SendChannel] and receiver using [ReceiveChannel]. |
| 153 | + * Conceptually, a channel is similar to [BlockingQueue][java.util.concurrent.BlockingQueue], |
| 154 | + * but it has suspending operations instead of blocking ones and it can be closed. |
| 155 | + */ |
| 156 | +public interface Channel<E> : SendChannel<E>, ReceiveChannel<E> |
| 157 | + |
| 158 | +/** |
| 159 | + * Indicates attempt to [send][SendChannel.send] on [isClosedForSend][SendChannel.isClosedForSend] channel. |
| 160 | + */ |
| 161 | +public class ClosedSendChannelException : IllegalStateException() |
| 162 | + |
| 163 | +/** |
| 164 | + * Indicates attempt to [receive][ReceiveChannel.receive] on [isClosedForReceive][ReceiveChannel.isClosedForReceive] |
| 165 | + * channel. |
| 166 | + */ |
| 167 | +public class ClosedReceiveChannelException : NoSuchElementException() |
0 commit comments