diff --git a/kotlinx-coroutines-core/common/src/channels/AbstractChannel.kt b/kotlinx-coroutines-core/common/src/channels/AbstractChannel.kt index 0835243e30..38f7c3bf16 100644 --- a/kotlinx-coroutines-core/common/src/channels/AbstractChannel.kt +++ b/kotlinx-coroutines-core/common/src/channels/AbstractChannel.kt @@ -167,7 +167,8 @@ internal abstract class AbstractSendChannel : SendChannel { // ------ SendChannel ------ public final override val isClosedForSend: Boolean get() = closedForSend != null - public final override val isFull: Boolean get() = queue.nextNode !is ReceiveOrClosed<*> && isBufferFull + public final override val isFull: Boolean get() = full + private val full: Boolean get() = queue.nextNode !is ReceiveOrClosed<*> && isBufferFull // TODO rename to `isFull` public final override suspend fun send(element: E) { // fast path -- try offer non-blocking @@ -402,7 +403,7 @@ internal abstract class AbstractSendChannel : SendChannel { private fun registerSelectSend(select: SelectInstance, element: E, block: suspend (SendChannel) -> R) { while (true) { if (select.isSelected) return - if (isFull) { + if (full) { val enqueueOp = TryEnqueueSendDesc(element, select, block) val enqueueResult = select.performAtomicIfNotSelected(enqueueOp) ?: return when { @@ -561,7 +562,8 @@ internal abstract class AbstractChannel : AbstractSendChannel(), Channel : AbstractSendChannel(), Channel registerSelectReceive(select: SelectInstance, block: suspend (E) -> R) { while (true) { if (select.isSelected) return - if (isEmpty) { + if (empty) { val enqueueOp = TryEnqueueReceiveDesc(select, block as (suspend (E?) -> R), nullOnClose = false) val enqueueResult = select.performAtomicIfNotSelected(enqueueOp) ?: return when { @@ -782,7 +784,7 @@ internal abstract class AbstractChannel : AbstractSendChannel(), Channel registerSelectReceiveOrNull(select: SelectInstance, block: suspend (E?) -> R) { while (true) { if (select.isSelected) return - if (isEmpty) { + if (empty) { val enqueueOp = TryEnqueueReceiveDesc(select, block, nullOnClose = true) val enqueueResult = select.performAtomicIfNotSelected(enqueueOp) ?: return when { diff --git a/kotlinx-coroutines-core/common/src/channels/Channel.kt b/kotlinx-coroutines-core/common/src/channels/Channel.kt index 351bd49e79..286196dc7b 100644 --- a/kotlinx-coroutines-core/common/src/channels/Channel.kt +++ b/kotlinx-coroutines-core/common/src/channels/Channel.kt @@ -30,14 +30,15 @@ public interface SendChannel { * Returns `true` if the channel is full (out of capacity) and the [send] attempt will suspend. * This function returns `false` for [isClosedForSend] channel. * - * **Note: This is an experimental api.** This property may change its semantics and/or name in the future. + * @suppress **Will be removed in next releases, no replacement.** */ @ExperimentalCoroutinesApi + @Deprecated(level = DeprecationLevel.ERROR, message = "Will be removed in next releases without replacement") public val isFull: Boolean /** - * Adds [element] into to this channel, suspending the caller while this channel [isFull], - * or throws exception if the channel [isClosedForSend] (see [close] for details). + * Adds [element] into to this channel, suspending the caller while the buffer of this channel is full + * or if it does not exist, or throws exception if the channel [isClosedForSend] (see [close] for details). * * Note, that closing a channel _after_ this function had suspended does not cause this suspended send invocation * to abort, because closing a channel is conceptually like sending a special "close token" over this channel. @@ -151,13 +152,14 @@ public interface ReceiveChannel { * Returns `true` if the channel is empty (contains no elements) and the [receive] attempt will suspend. * This function returns `false` for [isClosedForReceive] channel. * - * **Note: This is an experimental api.** This property may change its semantics and/or name in the future. + * @suppress **Will be removed in next releases, no replacement.** */ @ExperimentalCoroutinesApi + @Deprecated(level = DeprecationLevel.ERROR, message = "Will be removed in next releases without replacement") public val isEmpty: Boolean /** - * Retrieves and removes the element from this channel suspending the caller while this channel [isEmpty] + * Retrieves and removes the element from this channel suspending the caller while this channel is empty, * or throws [ClosedReceiveChannelException] if the channel [isClosedForReceive]. * If the channel was closed because of the exception, it is called a _failed_ channel and this function * throws the original [close][SendChannel.close] cause exception. @@ -188,7 +190,7 @@ public interface ReceiveChannel { public val onReceive: SelectClause1 /** - * Retrieves and removes the element from this channel suspending the caller while this channel [isEmpty] + * Retrieves and removes the element from this channel suspending the caller while this channel is empty, * or returns `null` if the channel is [closed][isClosedForReceive] without cause * or throws the original [close][SendChannel.close] cause exception if the channel has _failed_. * @@ -227,7 +229,7 @@ public interface ReceiveChannel { public val onReceiveOrNull: SelectClause1 /** - * Retrieves and removes the element from this channel, or returns `null` if this channel [isEmpty] + * Retrieves and removes the element from this channel, or returns `null` if this channel is empty * or is [isClosedForReceive] without cause. * It throws the original [close][SendChannel.close] cause exception if the channel has _failed_. */ @@ -273,9 +275,8 @@ public interface ReceiveChannel { */ public interface ChannelIterator { /** - * Returns `true` if the channel has more elements suspending the caller while this channel - * [isEmpty][ReceiveChannel.isEmpty] or returns `false` if the channel - * [isClosedForReceive][ReceiveChannel.isClosedForReceive] without cause. + * Returns `true` if the channel has more elements, suspending the caller while this channel is empty, + * or returns `false` if the channel [isClosedForReceive][ReceiveChannel.isClosedForReceive] without cause. * It throws the original [close][SendChannel.close] cause exception if the channel has _failed_. * * This function retrieves and removes the element from this channel for the subsequent invocation @@ -297,7 +298,7 @@ public interface ChannelIterator { /** * Retrieves and removes the element from this channel suspending the caller while this channel - * [isEmpty][ReceiveChannel.isEmpty] or throws [ClosedReceiveChannelException] if the channel + * is empty or throws [ClosedReceiveChannelException] if the channel * [isClosedForReceive][ReceiveChannel.isClosedForReceive] without cause. * It throws the original [close][SendChannel.close] cause exception if the channel has _failed_. * diff --git a/kotlinx-coroutines-core/common/test/channels/ArrayChannelTest.kt b/kotlinx-coroutines-core/common/test/channels/ArrayChannelTest.kt index 56a1c5a541..308f8f3c2a 100644 --- a/kotlinx-coroutines-core/common/test/channels/ArrayChannelTest.kt +++ b/kotlinx-coroutines-core/common/test/channels/ArrayChannelTest.kt @@ -11,12 +11,10 @@ class ArrayChannelTest : TestBase() { @Test fun testSimple() = runTest { val q = Channel(1) - check(q.isEmpty && !q.isFull) expect(1) val sender = launch { expect(4) q.send(1) // success -- buffered - check(!q.isEmpty && q.isFull) expect(5) q.send(2) // suspends (buffer full) expect(9) @@ -25,7 +23,6 @@ class ArrayChannelTest : TestBase() { val receiver = launch { expect(6) check(q.receive() == 1) // does not suspend -- took from buffer - check(!q.isEmpty && q.isFull) // waiting sender's element moved to buffer expect(7) check(q.receive() == 2) // does not suspend (takes from sender) expect(8) @@ -33,21 +30,20 @@ class ArrayChannelTest : TestBase() { expect(3) sender.join() receiver.join() - check(q.isEmpty && !q.isFull) finish(10) } @Test fun testClosedBufferedReceiveOrNull() = runTest { val q = Channel(1) - check(q.isEmpty && !q.isFull && !q.isClosedForSend && !q.isClosedForReceive) + check(!q.isClosedForSend && !q.isClosedForReceive) expect(1) launch { expect(5) - check(!q.isEmpty && !q.isFull && q.isClosedForSend && !q.isClosedForReceive) + check(q.isClosedForSend && !q.isClosedForReceive) assertEquals(42, q.receiveOrNull()) expect(6) - check(!q.isEmpty && !q.isFull && q.isClosedForSend && q.isClosedForReceive) + check(q.isClosedForSend && q.isClosedForReceive) assertEquals(null, q.receiveOrNull()) expect(7) } @@ -56,9 +52,9 @@ class ArrayChannelTest : TestBase() { expect(3) q.close() // goes on expect(4) - check(!q.isEmpty && !q.isFull && q.isClosedForSend && !q.isClosedForReceive) + check(q.isClosedForSend && !q.isClosedForReceive) yield() - check(!q.isEmpty && !q.isFull && q.isClosedForSend && q.isClosedForReceive) + check(q.isClosedForSend && q.isClosedForReceive) finish(8) } diff --git a/kotlinx-coroutines-core/common/test/channels/RendezvousChannelTest.kt b/kotlinx-coroutines-core/common/test/channels/RendezvousChannelTest.kt index 60bccef04d..fafda0d7da 100644 --- a/kotlinx-coroutines-core/common/test/channels/RendezvousChannelTest.kt +++ b/kotlinx-coroutines-core/common/test/channels/RendezvousChannelTest.kt @@ -11,7 +11,6 @@ class RendezvousChannelTest : TestBase() { @Test fun testSimple() = runTest { val q = Channel(Channel.RENDEZVOUS) - check(q.isEmpty && q.isFull) expect(1) val sender = launch { expect(4) @@ -31,14 +30,13 @@ class RendezvousChannelTest : TestBase() { expect(3) sender.join() receiver.join() - check(q.isEmpty && q.isFull) finish(10) } @Test fun testClosedReceiveOrNull() = runTest { val q = Channel(Channel.RENDEZVOUS) - check(q.isEmpty && q.isFull && !q.isClosedForSend && !q.isClosedForReceive) + check(!q.isClosedForSend && !q.isClosedForReceive) expect(1) launch { expect(3) @@ -51,9 +49,9 @@ class RendezvousChannelTest : TestBase() { q.send(42) expect(5) q.close() - check(!q.isEmpty && !q.isFull && q.isClosedForSend && q.isClosedForReceive) + check(q.isClosedForSend && q.isClosedForReceive) yield() - check(!q.isEmpty && !q.isFull && q.isClosedForSend && q.isClosedForReceive) + check(q.isClosedForSend && q.isClosedForReceive) finish(7) } diff --git a/kotlinx-coroutines-core/common/test/channels/TestChannelKind.kt b/kotlinx-coroutines-core/common/test/channels/TestChannelKind.kt index 465699e27c..6e1ee2bf69 100644 --- a/kotlinx-coroutines-core/common/test/channels/TestChannelKind.kt +++ b/kotlinx-coroutines-core/common/test/channels/TestChannelKind.kt @@ -54,6 +54,7 @@ private class ChannelViaBroadcast( val sub = broadcast.openSubscription() override val isClosedForReceive: Boolean get() = sub.isClosedForReceive + @Suppress("DEPRECATION_ERROR") override val isEmpty: Boolean get() = sub.isEmpty override suspend fun receive(): E = sub.receive()