Skip to content

Commit b28007e

Browse files
committed
Fix termination race condition in OperatorPublish.dispatch
1 parent 2532484 commit b28007e

File tree

1 file changed

+13
-3
lines changed

1 file changed

+13
-3
lines changed

src/main/java/rx/internal/operators/OperatorPublish.java

+13-3
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,15 @@ void dispatch() {
458458
boolean skipFinal = false;
459459
try {
460460
for (;;) {
461+
/*
462+
* We need to read terminalEvent before checking the queue for emptyness because
463+
* all enqueue happens before setting the terminal event.
464+
* If it were the other way around, when the emission is paused between
465+
* checking isEmpty and checking terminalEvent, some other thread might
466+
* have produced elements and set the terminalEvent and we'd quit emitting
467+
* prematurely.
468+
*/
469+
Object term = terminalEvent;
461470
/*
462471
* See if the queue is empty; since we need this information multiple
463472
* times later on, we read it one.
@@ -468,7 +477,7 @@ void dispatch() {
468477
// if the queue is empty and the terminal event was received, quit
469478
// and don't bother restoring emitting to false: no further activity is
470479
// possible at this point
471-
if (checkTerminated(terminalEvent, empty)) {
480+
if (checkTerminated(term, empty)) {
472481
skipFinal = true;
473482
return;
474483
}
@@ -508,10 +517,11 @@ void dispatch() {
508517
// it may happen everyone has unsubscribed between here and producers.get()
509518
// or we have no subscribers at all to begin with
510519
if (len == unsubscribed) {
520+
term = terminalEvent;
511521
// so let's consume a value from the queue
512522
Object v = queue.poll();
513523
// or terminate if there was a terminal event and the queue is empty
514-
if (checkTerminated(terminalEvent, v == null)) {
524+
if (checkTerminated(term, v == null)) {
515525
skipFinal = true;
516526
return;
517527
}
@@ -748,4 +758,4 @@ public void unsubscribe() {
748758
}
749759
}
750760
}
751-
}
761+
}

0 commit comments

Comments
 (0)