16
16
package rx .internal .operators ;
17
17
18
18
19
+ import java .util .concurrent .atomic .AtomicInteger ;
20
+
19
21
import rx .*;
20
22
import rx .internal .producers .ProducerArbiter ;
21
23
import rx .subscriptions .SerialSubscription ;
26
28
* empty, the results of the given Observable will be emitted.
27
29
* @param <T> the value type
28
30
*/
29
- public final class OperatorSwitchIfEmpty <T > implements Observable .Operator <T , T > {
30
- private final Observable <? extends T > alternate ;
31
+ public final class OnSubscribeSwitchIfEmpty <T > implements Observable .OnSubscribe <T > {
32
+
33
+ final Observable <? extends T > source ;
31
34
32
- public OperatorSwitchIfEmpty (Observable <? extends T > alternate ) {
35
+ final Observable <? extends T > alternate ;
36
+
37
+ public OnSubscribeSwitchIfEmpty (Observable <? extends T > source , Observable <? extends T > alternate ) {
38
+ this .source = source ;
33
39
this .alternate = alternate ;
34
40
}
35
41
36
42
@ Override
37
- public Subscriber <? super T > call (Subscriber <? super T > child ) {
43
+ public void call (Subscriber <? super T > child ) {
38
44
final SerialSubscription serial = new SerialSubscription ();
39
45
ProducerArbiter arbiter = new ProducerArbiter ();
40
46
final ParentSubscriber <T > parent = new ParentSubscriber <T >(child , serial , arbiter , alternate );
47
+
41
48
serial .set (parent );
42
49
child .add (serial );
43
50
child .setProducer (arbiter );
44
- return parent ;
51
+
52
+ parent .subscribe (source );
45
53
}
46
54
47
55
static final class ParentSubscriber <T > extends Subscriber <T > {
@@ -52,11 +60,15 @@ static final class ParentSubscriber<T> extends Subscriber<T> {
52
60
private final ProducerArbiter arbiter ;
53
61
private final Observable <? extends T > alternate ;
54
62
63
+ final AtomicInteger wip ;
64
+ volatile boolean active ;
65
+
55
66
ParentSubscriber (Subscriber <? super T > child , final SerialSubscription serial , ProducerArbiter arbiter , Observable <? extends T > alternate ) {
56
67
this .child = child ;
57
68
this .serial = serial ;
58
69
this .arbiter = arbiter ;
59
70
this .alternate = alternate ;
71
+ this .wip = new AtomicInteger ();
60
72
}
61
73
62
74
@ Override
@@ -69,14 +81,33 @@ public void onCompleted() {
69
81
if (!empty ) {
70
82
child .onCompleted ();
71
83
} else if (!child .isUnsubscribed ()) {
72
- subscribeToAlternate ();
84
+ active = false ;
85
+ subscribe (null );
73
86
}
74
87
}
75
88
76
- private void subscribeToAlternate () {
77
- AlternateSubscriber <T > as = new AlternateSubscriber <T >(child , arbiter );
78
- serial .set (as );
79
- alternate .unsafeSubscribe (as );
89
+ void subscribe (Observable <? extends T > source ) {
90
+ if (wip .getAndIncrement () == 0 ) {
91
+ do {
92
+ if (child .isUnsubscribed ()) {
93
+ break ;
94
+ }
95
+
96
+ if (!active ) {
97
+ if (source == null ) {
98
+ AlternateSubscriber <T > as = new AlternateSubscriber <T >(child , arbiter );
99
+ serial .set (as );
100
+ active = true ;
101
+ alternate .unsafeSubscribe (as );
102
+ } else {
103
+ active = true ;
104
+ source .unsafeSubscribe (this );
105
+ source = null ;
106
+ }
107
+ }
108
+
109
+ } while (wip .decrementAndGet () != 0 );
110
+ }
80
111
}
81
112
82
113
@ Override
0 commit comments