@@ -23,81 +23,83 @@ public fun <T : Any> Flow<T>.asPublisher(): Publisher<T> = FlowAsPublisher(this)
23
23
*/
24
24
@Suppress(" PublisherImplementation" )
25
25
private class FlowAsPublisher <T : Any >(private val flow : Flow <T >) : Publisher<T> {
26
-
27
26
override fun subscribe (subscriber : Subscriber <in T >? ) {
28
27
if (subscriber == null ) throw NullPointerException ()
29
28
subscriber.onSubscribe(FlowSubscription (flow, subscriber))
30
29
}
30
+ }
31
31
32
- private class FlowSubscription <T >(val flow : Flow <T >, val subscriber : Subscriber <in T >) : Subscription {
33
- @Volatile
34
- internal var canceled: Boolean = false
35
- private val requested = AtomicLong (0L )
36
- private val producer: AtomicReference <CancellableContinuation <Unit >? > = AtomicReference ()
37
-
38
- // This is actually optimizable
39
- private var job = GlobalScope .launch(Dispatchers .Unconfined , start = CoroutineStart .LAZY ) {
40
- try {
41
- consumeFlow()
42
- subscriber.onComplete()
43
- } catch (e: Throwable ) {
44
- // Failed with real exception, not due to cancellation
45
- if (! coroutineContext[Job ]!! .isCancelled) {
46
- subscriber.onError(e)
47
- }
32
+ /* * @suppress */
33
+ @InternalCoroutinesApi
34
+ public class FlowSubscription <T >(val flow : Flow <T >, val subscriber : Subscriber <in T >) : Subscription {
35
+ @Volatile
36
+ internal var canceled: Boolean = false
37
+ private val requested = AtomicLong (0L )
38
+ private val producer: AtomicReference <CancellableContinuation <Unit >? > = AtomicReference ()
39
+
40
+ // This is actually optimizable
41
+ private var job = GlobalScope .launch(Dispatchers .Unconfined , start = CoroutineStart .LAZY ) {
42
+ try {
43
+ consumeFlow()
44
+ subscriber.onComplete()
45
+ } catch (e: Throwable ) {
46
+ // Failed with real exception, not due to cancellation
47
+ if (! coroutineContext[Job ]!! .isCancelled) {
48
+ subscriber.onError(e)
48
49
}
49
50
}
51
+ }
50
52
51
- private suspend fun consumeFlow () {
52
- flow.collect { value ->
53
- if (! coroutineContext.isActive) {
54
- subscriber.onComplete()
55
- coroutineContext.ensureActive()
56
- }
53
+ private suspend fun consumeFlow () {
54
+ val ctx = coroutineContext
55
+ flow.collect { value ->
56
+ if (! coroutineContext.isActive) {
57
+ subscriber.onComplete()
58
+ coroutineContext.ensureActive()
59
+ }
57
60
58
- if (requested.get() == 0L ) {
59
- suspendCancellableCoroutine<Unit > {
60
- producer.set(it)
61
- if (requested.get() != 0L ) it.resumeSafely()
62
- }
61
+ if (requested.get() == 0L ) {
62
+ suspendCancellableCoroutine<Unit > {
63
+ producer.set(it)
64
+ if (requested.get() != 0L ) it.resumeSafely()
63
65
}
64
-
65
- requested.decrementAndGet()
66
- subscriber.onNext(value)
67
66
}
68
- }
69
67
70
- override fun cancel () {
71
- canceled = true
72
- job.cancel()
68
+ requested.decrementAndGet()
69
+ subscriber.onNext(value)
73
70
}
71
+ }
74
72
75
- override fun request (n : Long ) {
76
- if (n <= 0 ) {
77
- return
78
- }
73
+ override fun cancel () {
74
+ canceled = true
75
+ job.cancel()
76
+ }
77
+
78
+ override fun request (n : Long ) {
79
+ if (n <= 0 ) {
80
+ return
81
+ }
79
82
80
- if (canceled) return
83
+ if (canceled) return
81
84
82
- job.start()
83
- var snapshot: Long
84
- var newValue: Long
85
- do {
86
- snapshot = requested.get()
87
- newValue = snapshot + n
88
- if (newValue <= 0L ) newValue = Long .MAX_VALUE
89
- } while (! requested.compareAndSet(snapshot, newValue))
85
+ job.start()
86
+ var snapshot: Long
87
+ var newValue: Long
88
+ do {
89
+ snapshot = requested.get()
90
+ newValue = snapshot + n
91
+ if (newValue <= 0L ) newValue = Long .MAX_VALUE
92
+ } while (! requested.compareAndSet(snapshot, newValue))
90
93
91
- val prev = producer.get()
92
- if (prev == null || ! producer.compareAndSet(prev, null )) return
93
- prev.resumeSafely()
94
- }
94
+ val prev = producer.get()
95
+ if (prev == null || ! producer.compareAndSet(prev, null )) return
96
+ prev.resumeSafely()
97
+ }
95
98
96
- private fun CancellableContinuation<Unit>.resumeSafely () {
97
- val token = tryResume(Unit )
98
- if (token != null ) {
99
- completeResume(token)
100
- }
99
+ private fun CancellableContinuation<Unit>.resumeSafely () {
100
+ val token = tryResume(Unit )
101
+ if (token != null ) {
102
+ completeResume(token)
101
103
}
102
104
}
103
- }
105
+ }
0 commit comments