@@ -53,7 +53,7 @@ private static final class MergeSubscriber<T> extends Subscriber<Observable<? ex
53
53
private int wip ;
54
54
private boolean completed ;
55
55
56
- private SubscriptionIndexedRingBuffer <InnerSubscriber <T >> childrenSubscribers ;
56
+ private volatile SubscriptionIndexedRingBuffer <InnerSubscriber <T >> childrenSubscribers ;
57
57
58
58
private RxRingBuffer scalarValueQueue = null ;
59
59
@@ -244,11 +244,12 @@ private boolean drainQueuesIfNeeded() {
244
244
emitted = drainScalarValueQueue ();
245
245
drainChildrenQueues ();
246
246
} finally {
247
- if (!releaseEmitLock ()) {
248
- return true ;
249
- }
247
+ boolean moreToDrain = releaseEmitLock ();
250
248
// request outside of lock
251
249
request (emitted );
250
+ if (!moreToDrain ) {
251
+ return true ;
252
+ }
252
253
// otherwise we'll loop and get whatever was added
253
254
}
254
255
} else {
@@ -350,27 +351,29 @@ public void onCompleted() {
350
351
}
351
352
if (c ) {
352
353
// complete outside of lock
353
- actual . onCompleted ();
354
+ drainAndComplete ();
354
355
}
355
356
}
356
357
357
358
void completeInner (InnerSubscriber <T > s ) {
358
- try {
359
- boolean sendOnComplete = false ;
360
- synchronized (this ) {
361
- wip --;
362
- if (wip == 0 && completed ) {
363
- sendOnComplete = true ;
364
- }
365
- }
366
- if (sendOnComplete ) {
367
- actual .onCompleted ();
359
+ boolean sendOnComplete = false ;
360
+ synchronized (this ) {
361
+ wip --;
362
+ if (wip == 0 && completed ) {
363
+ sendOnComplete = true ;
368
364
}
369
- } finally {
370
- childrenSubscribers .remove (s .sindex );
365
+ }
366
+ childrenSubscribers .remove (s .sindex );
367
+ if (sendOnComplete ) {
368
+ drainAndComplete ();
371
369
}
372
370
}
373
371
372
+ private void drainAndComplete () {
373
+ drainQueuesIfNeeded (); // TODO need to confirm whether this is needed or not
374
+ actual .onCompleted ();
375
+ }
376
+
374
377
}
375
378
376
379
private static final class MergeProducer <T > implements Producer {
@@ -402,9 +405,10 @@ private static final class InnerSubscriber<T> extends Subscriber<T> {
402
405
final MergeSubscriber <T > parentSubscriber ;
403
406
final MergeProducer <T > producer ;
404
407
/** Make sure the inner termination events are delivered only once. */
405
- volatile int once ;
408
+ volatile int terminated ;
406
409
@ SuppressWarnings ("rawtypes" )
407
- static final AtomicIntegerFieldUpdater <InnerSubscriber > ONCE_UPDATER = AtomicIntegerFieldUpdater .newUpdater (InnerSubscriber .class , "once" );
410
+ static final AtomicIntegerFieldUpdater <InnerSubscriber > ONCE_TERMINATED = AtomicIntegerFieldUpdater .newUpdater (InnerSubscriber .class , "terminated" );
411
+
408
412
private final RxRingBuffer q = RxRingBuffer .getSpmcInstance ();
409
413
/* protected by emitLock */
410
414
int emitted = 0 ;
@@ -425,14 +429,14 @@ public void onNext(T t) {
425
429
@ Override
426
430
public void onError (Throwable e ) {
427
431
// it doesn't go through queues, it immediately onErrors and tears everything down
428
- if (ONCE_UPDATER .compareAndSet (this , 0 , 1 )) {
432
+ if (ONCE_TERMINATED .compareAndSet (this , 0 , 1 )) {
429
433
parentSubscriber .onError (e );
430
434
}
431
435
}
432
436
433
437
@ Override
434
438
public void onCompleted () {
435
- if (ONCE_UPDATER .compareAndSet (this , 0 , 1 )) {
439
+ if (ONCE_TERMINATED .compareAndSet (this , 0 , 1 )) {
436
440
emit (null , true );
437
441
}
438
442
}
0 commit comments