Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.google.common.testing;

import static com.google.common.base.Throwables.throwIfUnchecked;
import static com.google.common.collect.Sets.newConcurrentHashSet;
import static java.lang.Math.max;
import static java.util.concurrent.TimeUnit.SECONDS;
Expand All @@ -28,6 +29,8 @@
import com.google.errorprone.annotations.FormatMethod;
import com.google.j2objc.annotations.J2ObjCIncompatible;
import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Locale;
import java.util.Set;
import java.util.concurrent.CancellationException;
Expand All @@ -36,6 +39,7 @@
import java.util.concurrent.Future;
import java.util.concurrent.TimeoutException;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;

/**
* Testing utilities relating to garbage collection finalization.
Expand Down Expand Up @@ -142,15 +146,14 @@ private static long timeoutSeconds() {
*
* @throws RuntimeException if timed out or interrupted while waiting
*/
@SuppressWarnings("removal") // b/487687332
public static void awaitDone(Future<?> future) {
if (future.isDone()) {
return;
}
long timeoutSeconds = timeoutSeconds();
long deadline = System.nanoTime() + SECONDS.toNanos(timeoutSeconds);
do {
System.runFinalization();
runFinalization();
if (future.isDone()) {
return;
}
Expand All @@ -175,15 +178,14 @@ public static void awaitDone(Future<?> future) {
*
* @throws RuntimeException if timed out or interrupted while waiting
*/
@SuppressWarnings("removal") // b/487687332
public static void awaitDone(FinalizationPredicate predicate) {
if (predicate.isDone()) {
return;
}
long timeoutSeconds = timeoutSeconds();
long deadline = System.nanoTime() + SECONDS.toNanos(timeoutSeconds);
do {
System.runFinalization();
runFinalization();
if (predicate.isDone()) {
return;
}
Expand All @@ -204,15 +206,14 @@ public static void awaitDone(FinalizationPredicate predicate) {
*
* @throws RuntimeException if timed out or interrupted while waiting
*/
@SuppressWarnings("removal") // b/487687332
public static void await(CountDownLatch latch) {
if (latch.getCount() == 0) {
return;
}
long timeoutSeconds = timeoutSeconds();
long deadline = System.nanoTime() + SECONDS.toNanos(timeoutSeconds);
do {
System.runFinalization();
runFinalization();
if (latch.getCount() == 0) {
return;
}
Expand Down Expand Up @@ -303,7 +304,7 @@ public static void awaitFullGc() {
awaitClear(ref);

// Hope to catch some stragglers queued up behind our finalizable object
System.runFinalization();
runFinalization();
}

private static WeakReference<Object> createWeakReferenceWithFinalizer(
Expand Down Expand Up @@ -339,4 +340,28 @@ public void finalizeReferent() {
private static RuntimeException formatRuntimeException(String format, Object... args) {
return new RuntimeException(String.format(Locale.ROOT, format, args));
}

private static final @Nullable Method runFinalizationMethod = getRunFinalizationMethod();

private static @Nullable Method getRunFinalizationMethod() {
try {
return System.class.getMethod("runFinalization");
} catch (NoSuchMethodException | SecurityException e) {
return null;
}
}

private static void runFinalization() {
if (runFinalizationMethod == null) {
return;
}
try {
runFinalizationMethod.invoke(null);
} catch (InvocationTargetException e) {
throwIfUnchecked(e.getCause());
throw new AssertionError(e.getCause());
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
}
}
39 changes: 32 additions & 7 deletions guava-testlib/src/com/google/common/testing/GcFinalization.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.google.common.testing;

import static com.google.common.base.Throwables.throwIfUnchecked;
import static com.google.common.collect.Sets.newConcurrentHashSet;
import static java.lang.Math.max;
import static java.util.concurrent.TimeUnit.SECONDS;
Expand All @@ -28,6 +29,8 @@
import com.google.errorprone.annotations.FormatMethod;
import com.google.j2objc.annotations.J2ObjCIncompatible;
import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Locale;
import java.util.Set;
import java.util.concurrent.CancellationException;
Expand All @@ -36,6 +39,7 @@
import java.util.concurrent.Future;
import java.util.concurrent.TimeoutException;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;

/**
* Testing utilities relating to garbage collection finalization.
Expand Down Expand Up @@ -142,15 +146,14 @@ private static long timeoutSeconds() {
*
* @throws RuntimeException if timed out or interrupted while waiting
*/
@SuppressWarnings("removal") // b/487687332
public static void awaitDone(Future<?> future) {
if (future.isDone()) {
return;
}
long timeoutSeconds = timeoutSeconds();
long deadline = System.nanoTime() + SECONDS.toNanos(timeoutSeconds);
do {
System.runFinalization();
runFinalization();
if (future.isDone()) {
return;
}
Expand All @@ -175,15 +178,14 @@ public static void awaitDone(Future<?> future) {
*
* @throws RuntimeException if timed out or interrupted while waiting
*/
@SuppressWarnings("removal") // b/487687332
public static void awaitDone(FinalizationPredicate predicate) {
if (predicate.isDone()) {
return;
}
long timeoutSeconds = timeoutSeconds();
long deadline = System.nanoTime() + SECONDS.toNanos(timeoutSeconds);
do {
System.runFinalization();
runFinalization();
if (predicate.isDone()) {
return;
}
Expand All @@ -204,15 +206,14 @@ public static void awaitDone(FinalizationPredicate predicate) {
*
* @throws RuntimeException if timed out or interrupted while waiting
*/
@SuppressWarnings("removal") // b/487687332
public static void await(CountDownLatch latch) {
if (latch.getCount() == 0) {
return;
}
long timeoutSeconds = timeoutSeconds();
long deadline = System.nanoTime() + SECONDS.toNanos(timeoutSeconds);
do {
System.runFinalization();
runFinalization();
if (latch.getCount() == 0) {
return;
}
Expand Down Expand Up @@ -303,7 +304,7 @@ public static void awaitFullGc() {
awaitClear(ref);

// Hope to catch some stragglers queued up behind our finalizable object
System.runFinalization();
runFinalization();
}

private static WeakReference<Object> createWeakReferenceWithFinalizer(
Expand Down Expand Up @@ -339,4 +340,28 @@ public void finalizeReferent() {
private static RuntimeException formatRuntimeException(String format, Object... args) {
return new RuntimeException(String.format(Locale.ROOT, format, args));
}

private static final @Nullable Method runFinalizationMethod = getRunFinalizationMethod();

private static @Nullable Method getRunFinalizationMethod() {
try {
return System.class.getMethod("runFinalization");
} catch (NoSuchMethodException | SecurityException e) {
return null;
}
}

private static void runFinalization() {
if (runFinalizationMethod == null) {
return;
}
try {
runFinalizationMethod.invoke(null);
} catch (InvocationTargetException e) {
throwIfUnchecked(e.getCause());
throw new AssertionError(e.getCause());
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
}
}
Loading