@@ -41,11 +41,13 @@ public final class OperatorMulticast<T, R> extends ConnectableObservable<R> {
41
41
final Observable <? extends T > source ;
42
42
final Object guard ;
43
43
final Func0 <? extends Subject <? super T , ? extends R >> subjectFactory ;
44
- private final AtomicReference <Subject <? super T , ? extends R >> connectedSubject ;
45
- private final List <Subscriber <? super R >> waitingForConnect ;
44
+ final AtomicReference <Subject <? super T , ? extends R >> connectedSubject ;
45
+ final List <Subscriber <? super R >> waitingForConnect ;
46
46
47
47
/** Guarded by guard. */
48
- Subscriber <T > subscription ;
48
+ private Subscriber <T > subscription ;
49
+ // wraps subscription above for unsubscription using guard
50
+ private Subscription guardedSubscription ;
49
51
50
52
public OperatorMulticast (Observable <? extends T > source , final Func0 <? extends Subject <? super T , ? extends R >> subjectFactory ) {
51
53
this (new Object (), new AtomicReference <Subject <? super T , ? extends R >>(), new ArrayList <Subscriber <? super R >>(), source , subjectFactory );
@@ -77,15 +79,13 @@ public void call(Subscriber<? super R> subscriber) {
77
79
public void connect (Action1 <? super Subscription > connection ) {
78
80
// each time we connect we create a new Subject and Subscription
79
81
80
- boolean shouldSubscribe = false ;
81
-
82
82
// subscription is the state of whether we are connected or not
83
83
synchronized (guard ) {
84
84
if (subscription != null ) {
85
- // already connected, return as there is nothing to do
85
+ // already connected
86
+ connection .call (guardedSubscription );
86
87
return ;
87
88
} else {
88
- shouldSubscribe = true ;
89
89
// we aren't connected, so let's create a new Subject and connect
90
90
final Subject <? super T , ? extends R > subject = subjectFactory .call ();
91
91
// create new Subscriber that will pass-thru to the subject we just created
@@ -106,6 +106,26 @@ public void onNext(T args) {
106
106
subject .onNext (args );
107
107
}
108
108
};
109
+ final AtomicReference <Subscription > gs = new AtomicReference <Subscription >();
110
+ gs .set (Subscriptions .create (new Action0 () {
111
+ @ Override
112
+ public void call () {
113
+ Subscription s ;
114
+ synchronized (guard ) {
115
+ if ( guardedSubscription == gs .get ()) {
116
+ s = subscription ;
117
+ subscription = null ;
118
+ guardedSubscription = null ;
119
+ connectedSubject .set (null );
120
+ } else
121
+ return ;
122
+ }
123
+ if (s != null ) {
124
+ s .unsubscribe ();
125
+ }
126
+ }
127
+ }));
128
+ guardedSubscription = gs .get ();
109
129
110
130
// register any subscribers that are waiting with this new subject
111
131
for (Subscriber <? super R > s : waitingForConnect ) {
@@ -116,34 +136,20 @@ public void onNext(T args) {
116
136
// record the Subject so OnSubscribe can see it
117
137
connectedSubject .set (subject );
118
138
}
139
+
119
140
}
120
141
121
142
// in the lock above we determined we should subscribe, do it now outside the lock
122
- if (shouldSubscribe ) {
123
- // register a subscription that will shut this down
124
- connection .call (Subscriptions .create (new Action0 () {
125
- @ Override
126
- public void call () {
127
- Subscription s ;
128
- synchronized (guard ) {
129
- s = subscription ;
130
- subscription = null ;
131
- connectedSubject .set (null );
132
- }
133
- if (s != null ) {
134
- s .unsubscribe ();
135
- }
136
- }
137
- }));
143
+ // register a subscription that will shut this down
144
+ connection .call (guardedSubscription );
138
145
139
- // now that everything is hooked up let's subscribe
140
- // as long as the subscription is not null (which can happen if already unsubscribed)
141
- boolean subscriptionIsNull ;
142
- synchronized (guard ) {
143
- subscriptionIsNull = subscription == null ;
144
- }
145
- if (!subscriptionIsNull )
146
- source .subscribe (subscription );
146
+ // now that everything is hooked up let's subscribe
147
+ // as long as the subscription is not null (which can happen if already unsubscribed)
148
+ Subscriber <T > sub ;
149
+ synchronized (guard ) {
150
+ sub = subscription ;
147
151
}
152
+ if (sub != null )
153
+ source .subscribe (sub );
148
154
}
149
155
}
0 commit comments