@@ -54,7 +54,7 @@ private static final class MergeSubscriber<T> extends Subscriber<Observable<? ex
5454 private int wip ;
5555 private boolean completed ;
5656
57- private SubscriptionIndexedRingBuffer <InnerSubscriber <T >> childrenSubscribers ;
57+ private volatile SubscriptionIndexedRingBuffer <InnerSubscriber <T >> childrenSubscribers ;
5858
5959 private RxRingBuffer scalarValueQueue = null ;
6060
@@ -245,11 +245,12 @@ private boolean drainQueuesIfNeeded() {
245245 emitted = drainScalarValueQueue ();
246246 drainChildrenQueues ();
247247 } finally {
248- if (!releaseEmitLock ()) {
249- return true ;
250- }
248+ boolean moreToDrain = releaseEmitLock ();
251249 // request outside of lock
252250 request (emitted );
251+ if (!moreToDrain ) {
252+ return true ;
253+ }
253254 // otherwise we'll loop and get whatever was added
254255 }
255256 } else {
@@ -351,27 +352,29 @@ public void onCompleted() {
351352 }
352353 if (c ) {
353354 // complete outside of lock
354- actual . onCompleted ();
355+ drainAndComplete ();
355356 }
356357 }
357358
358359 void completeInner (InnerSubscriber <T > s ) {
359- try {
360- boolean sendOnComplete = false ;
361- synchronized (this ) {
362- wip --;
363- if (wip == 0 && completed ) {
364- sendOnComplete = true ;
365- }
366- }
367- if (sendOnComplete ) {
368- actual .onCompleted ();
360+ boolean sendOnComplete = false ;
361+ synchronized (this ) {
362+ wip --;
363+ if (wip == 0 && completed ) {
364+ sendOnComplete = true ;
369365 }
370- } finally {
371- childrenSubscribers .remove (s .sindex );
366+ }
367+ childrenSubscribers .remove (s .sindex );
368+ if (sendOnComplete ) {
369+ drainAndComplete ();
372370 }
373371 }
374372
373+ private void drainAndComplete () {
374+ drainQueuesIfNeeded (); // TODO need to confirm whether this is needed or not
375+ actual .onCompleted ();
376+ }
377+
375378 }
376379
377380 private static final class MergeProducer <T > implements Producer {
@@ -403,9 +406,10 @@ private static final class InnerSubscriber<T> extends Subscriber<T> {
403406 final MergeSubscriber <T > parentSubscriber ;
404407 final MergeProducer <T > producer ;
405408 /** Make sure the inner termination events are delivered only once. */
406- volatile int once ;
409+ volatile int terminated ;
407410 @ SuppressWarnings ("rawtypes" )
408- static final AtomicIntegerFieldUpdater <InnerSubscriber > ONCE_UPDATER = AtomicIntegerFieldUpdater .newUpdater (InnerSubscriber .class , "once" );
411+ static final AtomicIntegerFieldUpdater <InnerSubscriber > ONCE_TERMINATED = AtomicIntegerFieldUpdater .newUpdater (InnerSubscriber .class , "terminated" );
412+
409413 private final RxRingBuffer q = RxRingBuffer .getSpmcInstance ();
410414 /* protected by emitLock */
411415 int emitted = 0 ;
@@ -426,14 +430,14 @@ public void onNext(T t) {
426430 @ Override
427431 public void onError (Throwable e ) {
428432 // it doesn't go through queues, it immediately onErrors and tears everything down
429- if (ONCE_UPDATER .compareAndSet (this , 0 , 1 )) {
433+ if (ONCE_TERMINATED .compareAndSet (this , 0 , 1 )) {
430434 parentSubscriber .onError (e );
431435 }
432436 }
433437
434438 @ Override
435439 public void onCompleted () {
436- if (ONCE_UPDATER .compareAndSet (this , 0 , 1 )) {
440+ if (ONCE_TERMINATED .compareAndSet (this , 0 , 1 )) {
437441 emit (null , true );
438442 }
439443 }
0 commit comments