Fix the infinite loop bug for AndroidFuture.ThenCombine.
The bug was found and fixed in android.car.util.concurrent.AndroidFuture. The same fix is being duplicated from commit 9dcaf6862035676b2574e92cb72cba67ff0a879b. Bug: 218377773 Test: atest com.android.internal.infra.AndroidFutureTest Change-Id: I1e13d512a449a7330c74ed06f6afd90e3c4f9493
This commit is contained in:
@@ -455,7 +455,14 @@ public class AndroidFuture<T> extends CompletableFuture<T> implements Parcelable
|
||||
if (mSourceU != null) {
|
||||
// T done
|
||||
mResultT = (T) res;
|
||||
mSourceU.whenComplete(this);
|
||||
|
||||
// Subscribe to the second job completion.
|
||||
mSourceU.whenComplete((r, e) -> {
|
||||
// Mark the first job completion by setting mSourceU to null, so that next time
|
||||
// the execution flow goes to the else case below.
|
||||
mSourceU = null;
|
||||
accept(r, e);
|
||||
});
|
||||
} else {
|
||||
// U done
|
||||
try {
|
||||
|
||||
@@ -29,6 +29,7 @@ import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
/**
|
||||
* Unit test for {@link AndroidFuture}.
|
||||
@@ -154,4 +155,35 @@ public class AndroidFutureTest {
|
||||
expectThrows(ExecutionException.class, future1::get);
|
||||
assertThat(executionException.getCause()).isInstanceOf(UnsupportedOperationException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThenCombine() throws Exception {
|
||||
String nearFutureString = "near future comes";
|
||||
AndroidFuture<String> nearFuture = AndroidFuture.supply(() -> nearFutureString);
|
||||
String farFutureString = " before far future.";
|
||||
AndroidFuture<String> farFuture = AndroidFuture.supply(() -> farFutureString);
|
||||
AndroidFuture<String> combinedFuture =
|
||||
nearFuture.thenCombine(farFuture, ((s1, s2) -> s1 + s2));
|
||||
|
||||
assertThat(combinedFuture.get()).isEqualTo(nearFutureString + farFutureString);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testThenCombine_functionThrowingException() throws Exception {
|
||||
String nearFutureString = "near future comes";
|
||||
AndroidFuture<String> nearFuture = AndroidFuture.supply(() -> nearFutureString);
|
||||
String farFutureString = " before far future.";
|
||||
AndroidFuture<String> farFuture = AndroidFuture.supply(() -> farFutureString);
|
||||
UnsupportedOperationException exception = new UnsupportedOperationException(
|
||||
"Unsupported operation exception thrown!");
|
||||
BiFunction<String, String, String> throwingFunction = (s1, s2) -> {
|
||||
throw exception;
|
||||
};
|
||||
AndroidFuture<String> combinedFuture = nearFuture.thenCombine(farFuture, throwingFunction);
|
||||
|
||||
ExecutionException thrown = expectThrows(ExecutionException.class,
|
||||
() -> combinedFuture.get());
|
||||
|
||||
assertThat(thrown.getCause()).isSameInstanceAs(exception);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user