From e526cc394a659901edb9698935019860f76d4317 Mon Sep 17 00:00:00 2001 From: kaioni17 Date: Mon, 4 Nov 2024 23:27:01 -0800 Subject: [PATCH] Update BlockingFlowableIterable.onNext() to set error before cancel To avoid race with hasNext(), which checks for cancel first before checking for error. For example, in the following case, hasNext() may return false to the caller, making the caller assume the iterable finished successfully. 1. onNext() called cancel 2. hasNext() found the iterable is cancelled 3. hasNext() found that error is null thus returned false to the caller, without throwing the error 4. onNext() set error --- .../operators/flowable/BlockingFlowableIterable.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/BlockingFlowableIterable.java b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/BlockingFlowableIterable.java index 36436d1370..11239d04a7 100644 --- a/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/BlockingFlowableIterable.java +++ b/src/main/java/io/reactivex/rxjava3/internal/operators/flowable/BlockingFlowableIterable.java @@ -138,9 +138,12 @@ public void onSubscribe(Subscription s) { @Override public void onNext(T t) { if (!queue.offer(t)) { + // Error must be set first before calling cancel to avoid race + // with hasNext(), which checks for cancel first before checking + // for error. + error = new QueueOverflowException(); SubscriptionHelper.cancel(this); - - onError(new QueueOverflowException()); + onComplete(); } else { signalConsumer(); }