1616package rx .internal .operators ;
1717
1818import java .util .concurrent .ConcurrentLinkedQueue ;
19- import java .util .concurrent .atomic .AtomicInteger ;
20- import java .util .concurrent .atomic .AtomicLong ;
19+ import java .util .concurrent .atomic .*;
2120
22- import rx .Observable ;
21+ import rx .* ;
2322import rx .Observable .Operator ;
24- import rx .Producer ;
25- import rx .Subscriber ;
2623import rx .functions .Action0 ;
2724import rx .internal .producers .ProducerArbiter ;
2825import rx .observers .SerializedSubscriber ;
29- import rx .subscriptions .SerialSubscription ;
30- import rx .subscriptions .Subscriptions ;
26+ import rx .subscriptions .*;
3127
3228/**
3329 * Returns an Observable that emits the items emitted by two or more Observables, one after the other.
@@ -112,9 +108,19 @@ public void onStart() {
112108 }
113109
114110 private void requestFromChild (long n ) {
115- if (n <=0 ) return ;
111+ if (n <= 0 ) return ;
116112 // we track 'requested' so we know whether we should subscribe the next or not
117- long previous = BackpressureUtils .getAndAddRequest (requested , n );
113+
114+ final AtomicLong requestedField = requested ;
115+
116+ long previous ;
117+
118+ if (requestedField .get () != Long .MAX_VALUE ) {
119+ previous = BackpressureUtils .getAndAddRequest (requestedField , n );
120+ } else {
121+ previous = Long .MAX_VALUE ;
122+ }
123+
118124 arbiter .request (n );
119125 if (previous == 0 ) {
120126 if (currentSubscriber == null && wip .get () > 0 ) {
@@ -125,10 +131,6 @@ private void requestFromChild(long n) {
125131 }
126132 }
127133
128- private void decrementRequested () {
129- requested .decrementAndGet ();
130- }
131-
132134 @ Override
133135 public void onNext (Observable <? extends T > t ) {
134136 queue .add (nl .next (t ));
@@ -167,8 +169,10 @@ void subscribeNext() {
167169 child .onCompleted ();
168170 } else if (o != null ) {
169171 Observable <? extends T > obs = nl .getValue (o );
172+
170173 currentSubscriber = new ConcatInnerSubscriber <T >(this , child , arbiter );
171174 current .set (currentSubscriber );
175+
172176 obs .unsafeSubscribe (currentSubscriber );
173177 }
174178 } else {
@@ -179,14 +183,23 @@ void subscribeNext() {
179183 }
180184 }
181185 }
186+
187+ void produced (long c ) {
188+ if (c != 0L ) {
189+ arbiter .produced (c );
190+ BackpressureUtils .produced (requested , c );
191+ }
192+ }
182193 }
183194
184195 static class ConcatInnerSubscriber <T > extends Subscriber <T > {
185196
186197 private final Subscriber <T > child ;
187198 private final ConcatSubscriber <T > parent ;
188- private final AtomicInteger once = new AtomicInteger ();
199+ private final AtomicBoolean once = new AtomicBoolean ();
189200 private final ProducerArbiter arbiter ;
201+
202+ long produced ;
190203
191204 public ConcatInnerSubscriber (ConcatSubscriber <T > parent , Subscriber <T > child , ProducerArbiter arbiter ) {
192205 this .parent = parent ;
@@ -196,31 +209,33 @@ public ConcatInnerSubscriber(ConcatSubscriber<T> parent, Subscriber<T> child, Pr
196209
197210 @ Override
198211 public void onNext (T t ) {
212+ produced ++;
213+
199214 child .onNext (t );
200- parent .decrementRequested ();
201- arbiter .produced (1 );
202215 }
203216
204217 @ Override
205218 public void onError (Throwable e ) {
206- if (once .compareAndSet (0 , 1 )) {
219+ if (once .compareAndSet (false , true )) {
207220 // terminal error through parent so everything gets cleaned up, including this inner
208221 parent .onError (e );
209222 }
210223 }
211224
212225 @ Override
213226 public void onCompleted () {
214- if (once .compareAndSet (0 , 1 )) {
227+ if (once .compareAndSet (false , true )) {
228+ ConcatSubscriber <T > p = parent ;
229+ // signal the production count at once instead of one by one
230+ p .produced (produced );
215231 // terminal completion to parent so it continues to the next
216- parent .completeInner ();
232+ p .completeInner ();
217233 }
218234 }
219235
220236 @ Override
221237 public void setProducer (Producer producer ) {
222238 arbiter .setProducer (producer );
223239 }
224-
225240 }
226241}
0 commit comments