@@ -75,8 +75,15 @@ private static final class ObserveOnSubscriber<T> extends Subscriber<T> {
75
75
final NotificationLite <T > on = NotificationLite .instance ();
76
76
77
77
final Queue <Object > queue ;
78
- volatile boolean completed = false ;
79
- volatile boolean failure = false ;
78
+
79
+ // These are the states for the status field. The transitions are
80
+ // ACTIVE -> COMPLETED and ACTIVE -> ERRORED
81
+ private static final byte ACTIVE = 0 ;
82
+ private static final byte COMPLETED = 1 ;
83
+ private static final byte ERRORED = 2 ;
84
+
85
+ // the current status of the incoming stream, possible values listed above
86
+ volatile byte status = ACTIVE ;
80
87
81
88
volatile long requested = 0 ;
82
89
@ SuppressWarnings ("rawtypes" )
@@ -127,7 +134,7 @@ public void onStart() {
127
134
128
135
@ Override
129
136
public void onNext (final T t ) {
130
- if (isUnsubscribed () || completed ) {
137
+ if (isUnsubscribed () || status != ACTIVE ) {
131
138
return ;
132
139
}
133
140
if (!queue .offer (on .next (t ))) {
@@ -139,30 +146,23 @@ public void onNext(final T t) {
139
146
140
147
@ Override
141
148
public void onCompleted () {
142
- if (isUnsubscribed () || completed ) {
143
- return ;
144
- }
145
- if (error != null ) {
149
+ if (isUnsubscribed () || status != ACTIVE ) {
146
150
return ;
147
151
}
148
- completed = true ;
152
+ status = COMPLETED ;
149
153
schedule ();
150
154
}
151
155
152
156
@ Override
153
157
public void onError (final Throwable e ) {
154
- if (isUnsubscribed () || completed ) {
155
- return ;
156
- }
157
- if (error != null ) {
158
+ if (isUnsubscribed () || status != ACTIVE ) {
158
159
return ;
159
160
}
160
161
error = e ;
161
162
// unsubscribe eagerly since time will pass before the scheduled onError results in an unsubscribe event
162
163
unsubscribe ();
163
164
// mark failure so the polling thread will skip onNext still in the queue
164
- completed = true ;
165
- failure = true ;
165
+ status = ERRORED ;
166
166
schedule ();
167
167
}
168
168
@@ -191,41 +191,37 @@ void pollQueue() {
191
191
*/
192
192
counter = 1 ;
193
193
194
- // middle:
195
194
while (!scheduledUnsubscribe .isUnsubscribed ()) {
196
- if (failure ) {
195
+ if (status == ERRORED ) {
197
196
child .onError (error );
198
197
return ;
199
- } else {
200
- if (requested == 0 && completed && queue .isEmpty ()) {
201
- child .onCompleted ();
202
- return ;
203
- }
204
- if (REQUESTED .getAndDecrement (this ) != 0 ) {
205
- Object o = queue .poll ();
206
- if (o == null ) {
207
- if (completed ) {
208
- if (failure ) {
209
- child .onError (error );
210
- } else {
211
- child .onCompleted ();
212
- }
213
- return ;
214
- }
215
- // nothing in queue
198
+ } else if (requested == 0 && status == COMPLETED && queue .isEmpty ()) {
199
+ child .onCompleted ();
200
+ return ;
201
+ } else if (REQUESTED .getAndDecrement (this ) != 0 ) {
202
+ Object o = queue .poll ();
203
+ if (o == null ) {
204
+ // nothing in queue
205
+ if (status == ERRORED ) {
206
+ child .onError (error );
207
+ return ;
208
+ } else if (status == COMPLETED ) {
209
+ child .onCompleted ();
210
+ return ;
211
+ } else {
216
212
REQUESTED .incrementAndGet (this );
217
213
break ;
218
- } else {
219
- if (!on .accept (child , o )) {
220
- // non-terminal event so let's increment count
221
- emitted ++;
222
- }
223
214
}
224
215
} else {
225
- // we hit the end ... so increment back to 0 again
226
- REQUESTED .incrementAndGet (this );
227
- break ;
216
+ if (!on .accept (child , o )) {
217
+ // non-terminal event so let's increment count
218
+ emitted ++;
219
+ }
228
220
}
221
+ } else {
222
+ // we hit the end ... so increment back to 0 again
223
+ REQUESTED .incrementAndGet (this );
224
+ break ;
229
225
}
230
226
}
231
227
} while (COUNTER_UPDATER .decrementAndGet (this ) > 0 );
0 commit comments