@@ -238,7 +238,7 @@ public sealed interface SelectInstance<in R> {
238
238
*/
239
239
public fun selectInRegistrationPhase (internalResult : Any? )
240
240
}
241
- internal interface SelectInstanceInternal <R >: SelectInstance <R >, Waiter
241
+ internal interface SelectInstanceInternal <R >: SelectInstance <R >, Waiter , SegmentDisposable
242
242
243
243
@PublishedApi
244
244
internal open class SelectImplementation <R > constructor(
@@ -380,7 +380,12 @@ internal open class SelectImplementation<R> constructor(
380
380
* After that, if the clause is successfully registered (so, it has not completed immediately),
381
381
* this [DisposableHandle] is stored into the corresponding [ClauseData] instance.
382
382
*/
383
- private var disposableHandle: DisposableHandle ? = null
383
+ private var disposableHandleOrSegment: Any? = null
384
+
385
+ /* *
386
+ * TODO
387
+ */
388
+ private var indexInSegment: Int = - 1
384
389
385
390
/* *
386
391
* Stores the result passed via [selectInRegistrationPhase] during clause registration
@@ -469,8 +474,10 @@ internal open class SelectImplementation<R> constructor(
469
474
// This also guarantees that the list of clauses cannot be cleared
470
475
// in the registration phase, so it is safe to read it with "!!".
471
476
if (! reregister) clauses!! + = this
472
- disposableHandle = this @SelectImplementation.disposableHandle
473
- this @SelectImplementation.disposableHandle = null
477
+ disposableHandleOrSegment = this @SelectImplementation.disposableHandleOrSegment
478
+ indexInSegment = this @SelectImplementation.indexInSegment
479
+ this @SelectImplementation.disposableHandleOrSegment = null
480
+ this @SelectImplementation.indexInSegment = - 1
474
481
} else {
475
482
// This clause has been selected!
476
483
// Update the state correspondingly.
@@ -493,7 +500,12 @@ internal open class SelectImplementation<R> constructor(
493
500
}
494
501
495
502
override fun disposeOnCompletion (disposableHandle : DisposableHandle ) {
496
- this .disposableHandle = disposableHandle
503
+ this .disposableHandleOrSegment = disposableHandle
504
+ }
505
+
506
+ override fun disposeOnCancellation (segment : Segment <* >, index : Int ) {
507
+ this .disposableHandleOrSegment = segment
508
+ this .indexInSegment = index
497
509
}
498
510
499
511
override fun selectInRegistrationPhase (internalResult : Any? ) {
@@ -556,7 +568,8 @@ internal open class SelectImplementation<R> constructor(
556
568
*/
557
569
private fun reregisterClause (clauseObject : Any ) {
558
570
val clause = findClause(clauseObject)!! // it is guaranteed that the corresponding clause is presented
559
- clause.disposableHandle = null
571
+ clause.disposableHandleOrSegment = null
572
+ clause.indexInSegment = - 1
560
573
clause.register(reregister = true )
561
574
}
562
575
@@ -692,7 +705,7 @@ internal open class SelectImplementation<R> constructor(
692
705
// Invoke all cancellation handlers except for the
693
706
// one related to the selected clause, if specified.
694
707
clauses.forEach { clause ->
695
- if (clause != = selectedClause) clause.disposableHandle?. dispose()
708
+ if (clause != = selectedClause) clause.dispose()
696
709
}
697
710
// We do need to clean all the data to avoid memory leaks.
698
711
this .state.value = STATE_COMPLETED
@@ -716,7 +729,7 @@ internal open class SelectImplementation<R> constructor(
716
729
// a concurrent clean-up procedure has already completed, and it is safe to finish.
717
730
val clauses = this .clauses ? : return
718
731
// Remove this `select` instance from all the clause object (channels, mutexes, etc.).
719
- clauses.forEach { it.disposableHandle?. dispose() }
732
+ clauses.forEach { it.dispose() }
720
733
// We do need to clean all the data to avoid memory leaks.
721
734
this .internalResult = NO_RESULT
722
735
this .clauses = null
@@ -731,9 +744,11 @@ internal open class SelectImplementation<R> constructor(
731
744
private val processResFunc : ProcessResultFunction ,
732
745
private val param : Any? , // the user-specified param
733
746
private val block : Any , // the user-specified block, which should be called if this clause becomes selected
734
- @JvmField val onCancellationConstructor : OnCancellationConstructor ? ,
735
- @JvmField var disposableHandle : DisposableHandle ? = null
747
+ @JvmField val onCancellationConstructor : OnCancellationConstructor ?
736
748
) {
749
+ @JvmField var disposableHandleOrSegment: Any? = null
750
+ @JvmField var indexInSegment: Int = - 1
751
+
737
752
/* *
738
753
* Tries to register the specified [select] instance in [clauseObject] and check
739
754
* whether the registration succeeded or a rendezvous has happened during the registration.
@@ -788,6 +803,17 @@ internal open class SelectImplementation<R> constructor(
788
803
}
789
804
}
790
805
806
+ fun dispose () {
807
+ with (disposableHandleOrSegment) {
808
+ if (this is Segment <* >) {
809
+ this .onCancellation(indexInSegment, null )
810
+ } else {
811
+ this as DisposableHandle
812
+ this .dispose()
813
+ }
814
+ }
815
+ }
816
+
791
817
fun createOnCancellationAction (select : SelectInstance <* >, internalResult : Any? ) =
792
818
onCancellationConstructor?.invoke(select, param, internalResult)
793
819
}
0 commit comments