From 338f2a11350480cef409f64eff4a2d307be7e05a Mon Sep 17 00:00:00 2001 From: kaioni17 Date: Thu, 21 Nov 2024 09:10:11 -0800 Subject: [PATCH] Update BlockingFlowableIterable.onNext() to set error before cancel (#7789) 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(); }