@@ -398,6 +398,11 @@ public abstract class AbstractSendChannel<E> : SendChannel<E> {
398
398
remove()
399
399
}
400
400
401
+ override fun resumeSendClosed (closed : Closed <* >) {
402
+ if (select.trySelect(null ))
403
+ select.resumeSelectCancellableWithException(closed.sendException)
404
+ }
405
+
401
406
override fun toString (): String = " SendSelect($pollResult )[$channel , $select ]"
402
407
}
403
408
@@ -407,6 +412,7 @@ public abstract class AbstractSendChannel<E> : SendChannel<E> {
407
412
override val pollResult: Any? get() = element
408
413
override fun tryResumeSend (idempotent : Any? ): Any? = SEND_RESUMED
409
414
override fun completeResumeSend (token : Any ) { check(token == = SEND_RESUMED ) }
415
+ override fun resumeSendClosed (closed : Closed <* >) {}
410
416
}
411
417
}
412
418
@@ -567,6 +573,25 @@ public abstract class AbstractChannel<E> : AbstractSendChannel<E>(), Channel<E>
567
573
return if (result == = POLL_FAILED ) null else receiveOrNullResult(result)
568
574
}
569
575
576
+ override fun consumeAll () {
577
+ close(cause = null )
578
+ // now cleanup send queue
579
+ consumeAllInternal()
580
+ }
581
+
582
+ // Note: this function is invoked when channel is already closed
583
+ protected open fun consumeAllInternal () {
584
+ val closed = closedForSend ? : error(" Cannot happen" )
585
+ while (true ) {
586
+ val send = takeFirstSendOrPeekClosed() ? : error(" Cannot happen" )
587
+ if (send is Closed <* >) {
588
+ check(send == = closed)
589
+ return // cleaned
590
+ }
591
+ send.resumeSendClosed(closed)
592
+ }
593
+ }
594
+
570
595
public final override fun iterator (): ChannelIterator <E > = Itr (this )
571
596
572
597
// ------ registerSelectReceive ------
@@ -909,6 +934,7 @@ public interface Send {
909
934
val pollResult: Any? // E | Closed
910
935
fun tryResumeSend (idempotent : Any? ): Any?
911
936
fun completeResumeSend (token : Any )
937
+ fun resumeSendClosed (closed : Closed <* >)
912
938
}
913
939
914
940
/* *
@@ -922,7 +948,7 @@ public interface ReceiveOrClosed<in E> {
922
948
}
923
949
924
950
/* *
925
- * Represents closed channel .
951
+ * Represents sender for a specific element .
926
952
* @suppress **This is unstable API and it is subject to change.**
927
953
*/
928
954
@Suppress(" UNCHECKED_CAST" )
@@ -932,6 +958,7 @@ public class SendElement(
932
958
) : LockFreeLinkedListNode(), Send {
933
959
override fun tryResumeSend (idempotent : Any? ): Any? = cont.tryResume(Unit , idempotent)
934
960
override fun completeResumeSend (token : Any ) = cont.completeResume(token)
961
+ override fun resumeSendClosed (closed : Closed <* >) = cont.resumeWithException(closed.sendException)
935
962
override fun toString (): String = " SendElement($pollResult )[$cont ]"
936
963
}
937
964
@@ -951,6 +978,7 @@ public class Closed<in E>(
951
978
override fun completeResumeSend (token : Any ) { check(token == = CLOSE_RESUMED ) }
952
979
override fun tryResumeReceive (value : E , idempotent : Any? ): Any? = CLOSE_RESUMED
953
980
override fun completeResumeReceive (token : Any ) { check(token == = CLOSE_RESUMED ) }
981
+ override fun resumeSendClosed (closed : Closed <* >) = error(" Should be never invoked" )
954
982
override fun toString (): String = " Closed[$closeCause ]"
955
983
}
956
984
0 commit comments