@@ -176,8 +176,8 @@ internal abstract class AbstractSendChannel<E> : SendChannel<E> {
176
176
result == = OFFER_SUCCESS -> true
177
177
// We should check for closed token on offer as well, otherwise offer won't be linearizable
178
178
// in the face of concurrent close()
179
- result == = OFFER_FAILED -> throw closedForSend?.sendException ? : return false
180
- result is Closed <* > -> throw result.sendException
179
+ result == = OFFER_FAILED -> throw closedForSend?.sendException?. let { recoverStackTrace(it) } ? : return false
180
+ result is Closed <* > -> throw recoverStackTrace( result.sendException)
181
181
else -> error(" offerInternal returned $result " )
182
182
}
183
183
}
@@ -194,7 +194,7 @@ internal abstract class AbstractSendChannel<E> : SendChannel<E> {
194
194
}
195
195
is Closed <* > -> {
196
196
helpClose(enqueueResult)
197
- cont.resumeWithException (enqueueResult.sendException)
197
+ cont.resumeWithStackTrace (enqueueResult.sendException)
198
198
return @sc
199
199
}
200
200
}
@@ -208,7 +208,7 @@ internal abstract class AbstractSendChannel<E> : SendChannel<E> {
208
208
offerResult == = OFFER_FAILED -> continue @loop
209
209
offerResult is Closed <* > -> {
210
210
helpClose(offerResult)
211
- cont.resumeWithException (offerResult.sendException)
211
+ cont.resumeWithStackTrace (offerResult.sendException)
212
212
return @sc
213
213
}
214
214
else -> error(" offerInternal returned $offerResult " )
@@ -408,7 +408,7 @@ internal abstract class AbstractSendChannel<E> : SendChannel<E> {
408
408
when {
409
409
enqueueResult == = ALREADY_SELECTED -> return
410
410
enqueueResult == = ENQUEUE_FAILED -> {} // retry
411
- enqueueResult is Closed <* > -> throw enqueueResult.sendException
411
+ enqueueResult is Closed <* > -> throw recoverStackTrace( enqueueResult.sendException)
412
412
else -> error(" performAtomicIfNotSelected(TryEnqueueSendDesc) returned $enqueueResult " )
413
413
}
414
414
} else {
@@ -420,7 +420,7 @@ internal abstract class AbstractSendChannel<E> : SendChannel<E> {
420
420
block.startCoroutineUnintercepted(receiver = this , completion = select.completion)
421
421
return
422
422
}
423
- offerResult is Closed <* > -> throw offerResult.sendException
423
+ offerResult is Closed <* > -> throw recoverStackTrace( offerResult.sendException)
424
424
else -> error(" offerSelectInternal returned $offerResult " )
425
425
}
426
426
}
@@ -574,7 +574,7 @@ internal abstract class AbstractChannel<E> : AbstractSendChannel<E>(), Channel<E
574
574
575
575
@Suppress(" UNCHECKED_CAST" )
576
576
private fun receiveResult (result : Any? ): E {
577
- if (result is Closed <* >) throw result.receiveException
577
+ if (result is Closed <* >) throw recoverStackTrace( result.receiveException)
578
578
return result as E
579
579
}
580
580
@@ -590,7 +590,7 @@ internal abstract class AbstractChannel<E> : AbstractSendChannel<E>(), Channel<E
590
590
// hm... something is not right. try to poll
591
591
val result = pollInternal()
592
592
if (result is Closed <* >) {
593
- cont.resumeWithException (result.receiveException)
593
+ cont.resumeWithStackTrace (result.receiveException)
594
594
return @sc
595
595
}
596
596
if (result != = POLL_FAILED ) {
@@ -620,7 +620,7 @@ internal abstract class AbstractChannel<E> : AbstractSendChannel<E>(), Channel<E
620
620
@Suppress(" UNCHECKED_CAST" )
621
621
private fun receiveOrNullResult (result : Any? ): E ? {
622
622
if (result is Closed <* >) {
623
- if (result.closeCause != null ) throw result.closeCause
623
+ if (result.closeCause != null ) throw recoverStackTrace( result.closeCause)
624
624
return null
625
625
}
626
626
return result as E
@@ -641,7 +641,7 @@ internal abstract class AbstractChannel<E> : AbstractSendChannel<E>(), Channel<E
641
641
if (result.closeCause == null )
642
642
cont.resume(null )
643
643
else
644
- cont.resumeWithException (result.closeCause)
644
+ cont.resumeWithStackTrace (result.closeCause)
645
645
return @sc
646
646
}
647
647
if (result != = POLL_FAILED ) {
@@ -758,7 +758,7 @@ internal abstract class AbstractChannel<E> : AbstractSendChannel<E>(), Channel<E
758
758
when {
759
759
pollResult == = ALREADY_SELECTED -> return
760
760
pollResult == = POLL_FAILED -> {} // retry
761
- pollResult is Closed <* > -> throw pollResult.receiveException
761
+ pollResult is Closed <* > -> throw recoverStackTrace( pollResult.receiveException)
762
762
else -> {
763
763
block.startCoroutineUnintercepted(pollResult as E , select.completion)
764
764
return
@@ -797,8 +797,9 @@ internal abstract class AbstractChannel<E> : AbstractSendChannel<E>(), Channel<E
797
797
if (select.trySelect(null ))
798
798
block.startCoroutineUnintercepted(null , select.completion)
799
799
return
800
- } else
801
- throw pollResult.closeCause
800
+ } else {
801
+ throw recoverStackTrace(pollResult.closeCause)
802
+ }
802
803
}
803
804
else -> {
804
805
// selected successfully
@@ -857,7 +858,7 @@ internal abstract class AbstractChannel<E> : AbstractSendChannel<E>(), Channel<E
857
858
858
859
private fun hasNextResult (result : Any? ): Boolean {
859
860
if (result is Closed <* >) {
860
- if (result.closeCause != null ) throw result.receiveException
861
+ if (result.closeCause != null ) recoverStackTrace( throw result.receiveException)
861
862
return false
862
863
}
863
864
return true
@@ -878,7 +879,7 @@ internal abstract class AbstractChannel<E> : AbstractSendChannel<E>(), Channel<E
878
879
if (result.closeCause == null )
879
880
cont.resume(false )
880
881
else
881
- cont.resumeWithException (result.receiveException)
882
+ cont.resumeWithStackTrace (result.receiveException)
882
883
return @sc
883
884
}
884
885
if (result != = POLL_FAILED ) {
@@ -891,7 +892,7 @@ internal abstract class AbstractChannel<E> : AbstractSendChannel<E>(), Channel<E
891
892
@Suppress(" UNCHECKED_CAST" )
892
893
override suspend fun next (): E {
893
894
val result = this .result
894
- if (result is Closed <* >) throw result.receiveException
895
+ if (result is Closed <* >) throw recoverStackTrace( result.receiveException)
895
896
if (result != = POLL_FAILED ) {
896
897
this .result = POLL_FAILED
897
898
return result as E
@@ -911,7 +912,7 @@ internal abstract class AbstractChannel<E> : AbstractSendChannel<E>(), Channel<E
911
912
if (closed.closeCause == null && nullOnClose)
912
913
cont.resume(null )
913
914
else
914
- cont.resumeWithException (closed.receiveException)
915
+ cont.resumeWithStackTrace (closed.receiveException)
915
916
}
916
917
override fun toString (): String = " ReceiveElement[$cont ,nullOnClose=$nullOnClose ]"
917
918
}
@@ -943,10 +944,11 @@ internal abstract class AbstractChannel<E> : AbstractSendChannel<E>(), Channel<E
943
944
}
944
945
945
946
override fun resumeReceiveClosed (closed : Closed <* >) {
946
- val token = if (closed.closeCause == null )
947
+ val token = if (closed.closeCause == null ) {
947
948
cont.tryResume(false )
948
- else
949
- cont.tryResumeWithException(closed.receiveException)
949
+ } else {
950
+ cont.tryResumeWithException(recoverStackTrace(closed.receiveException, cont))
951
+ }
950
952
if (token != null ) {
951
953
iterator.result = closed
952
954
cont.completeResume(token)
@@ -1056,7 +1058,7 @@ internal class SendElement(
1056
1058
) : LockFreeLinkedListNode(), Send {
1057
1059
override fun tryResumeSend (idempotent : Any? ): Any? = cont.tryResume(Unit , idempotent)
1058
1060
override fun completeResumeSend (token : Any ) = cont.completeResume(token)
1059
- override fun resumeSendClosed (closed : Closed <* >) = cont.resumeWithException (closed.sendException)
1061
+ override fun resumeSendClosed (closed : Closed <* >) = cont.resumeWithStackTrace (closed.sendException)
1060
1062
override fun toString (): String = " SendElement($pollResult )[$cont ]"
1061
1063
}
1062
1064
0 commit comments