15
15
*/
16
16
package rx .operators ;
17
17
18
+ import java .util .concurrent .atomic .AtomicIntegerFieldUpdater ;
18
19
import java .util .concurrent .atomic .AtomicLongFieldUpdater ;
19
20
20
21
import rx .Observable .Operator ;
21
22
import rx .Scheduler ;
22
23
import rx .Subscriber ;
24
+ import rx .Subscription ;
23
25
import rx .functions .Action0 ;
24
26
import rx .schedulers .ImmediateScheduler ;
25
27
import rx .schedulers .TrampolineScheduler ;
@@ -59,6 +61,7 @@ public Subscriber<? super T> call(Subscriber<? super T> child) {
59
61
private static final class ObserveOnSubscriber <T > extends Subscriber <T > {
60
62
final Subscriber <? super T > observer ;
61
63
private final Scheduler .Worker recursiveScheduler ;
64
+ private final ScheduledUnsubscribe scheduledUnsubscribe ;
62
65
final NotificationLite <T > on = NotificationLite .instance ();
63
66
/** Guarded by this. */
64
67
private FastList queue = new FastList ();
@@ -72,11 +75,15 @@ public ObserveOnSubscriber(Scheduler scheduler, Subscriber<? super T> subscriber
72
75
super (subscriber );
73
76
this .observer = subscriber ;
74
77
this .recursiveScheduler = scheduler .createWorker ();
75
- subscriber .add (recursiveScheduler );
78
+ this .scheduledUnsubscribe = new ScheduledUnsubscribe (recursiveScheduler );
79
+ subscriber .add (scheduledUnsubscribe );
76
80
}
77
81
78
82
@ Override
79
83
public void onNext (final T t ) {
84
+ if (scheduledUnsubscribe .isUnsubscribed ()) {
85
+ return ;
86
+ }
80
87
synchronized (this ) {
81
88
queue .add (on .next (t ));
82
89
}
@@ -85,6 +92,9 @@ public void onNext(final T t) {
85
92
86
93
@ Override
87
94
public void onCompleted () {
95
+ if (scheduledUnsubscribe .isUnsubscribed ()) {
96
+ return ;
97
+ }
88
98
synchronized (this ) {
89
99
queue .add (on .completed ());
90
100
}
@@ -93,6 +103,9 @@ public void onCompleted() {
93
103
94
104
@ Override
95
105
public void onError (final Throwable e ) {
106
+ if (scheduledUnsubscribe .isUnsubscribed ()) {
107
+ return ;
108
+ }
96
109
synchronized (this ) {
97
110
queue .add (on .error (e ));
98
111
}
@@ -153,4 +166,32 @@ public void add(Object o) {
153
166
size = s + 1 ;
154
167
}
155
168
}
169
+ static final class ScheduledUnsubscribe implements Subscription {
170
+ final Scheduler .Worker worker ;
171
+ volatile int once ;
172
+ static final AtomicIntegerFieldUpdater <ScheduledUnsubscribe > ONCE_UPDATER
173
+ = AtomicIntegerFieldUpdater .newUpdater (ScheduledUnsubscribe .class , "once" );
174
+
175
+ public ScheduledUnsubscribe (Scheduler .Worker worker ) {
176
+ this .worker = worker ;
177
+ }
178
+
179
+ @ Override
180
+ public boolean isUnsubscribed () {
181
+ return once != 0 ;
182
+ }
183
+
184
+ @ Override
185
+ public void unsubscribe () {
186
+ if (ONCE_UPDATER .getAndSet (this , 1 ) == 0 ) {
187
+ worker .schedule (new Action0 () {
188
+ @ Override
189
+ public void call () {
190
+ worker .unsubscribe ();
191
+ }
192
+ });
193
+ }
194
+ }
195
+
196
+ }
156
197
}
0 commit comments