@@ -41,8 +41,7 @@ private class SubscriptionChannel<T>(
41
41
require(request >= 0 ) { " Invalid request size: $request " }
42
42
}
43
43
44
- @Volatile
45
- private var subscription: Subscription ? = null
44
+ private val _subscription = atomic<Subscription ?>(null )
46
45
47
46
// requested from subscription minus number of received minus number of enqueued receivers,
48
47
// can be negative if we have receivers, but no subscription yet
@@ -52,7 +51,7 @@ private class SubscriptionChannel<T>(
52
51
@Suppress(" CANNOT_OVERRIDE_INVISIBLE_MEMBER" )
53
52
override fun onReceiveEnqueued () {
54
53
_requested .loop { wasRequested ->
55
- val subscription = this .subscription
54
+ val subscription = _subscription .value
56
55
val needRequested = wasRequested - 1
57
56
if (subscription != null && needRequested < 0 ) { // need to request more from subscription
58
57
// try to fixup by making request
@@ -73,13 +72,12 @@ private class SubscriptionChannel<T>(
73
72
74
73
@Suppress(" CANNOT_OVERRIDE_INVISIBLE_MEMBER" )
75
74
override fun onClosedIdempotent (closed : LockFreeLinkedListNode ) {
76
- subscription?.cancel()
77
- subscription = null // optimization -- no need to cancel it again
75
+ _subscription .getAndSet(null )?.cancel() // cancel exactly once
78
76
}
79
77
80
78
// Subscriber overrides
81
79
override fun onSubscribe (s : Subscription ) {
82
- subscription = s
80
+ _subscription .value = s
83
81
while (true ) { // lock-free loop on _requested
84
82
if (isClosedForSend) {
85
83
s.cancel()
0 commit comments