Introduce RefCounted#mustIncRef (#102515)

In several places we acquire a ref to a resource that we are certain is
not closed, so this commit adds a utility for asserting this to be the
case. This also helps a little with mocks since boolean methods like
`tryIncRef()` return `false` on mock objects by default, but void
methods like `mustIncRef()` default to being a no-op.
This commit is contained in:
David Turner 2023-11-23 21:40:43 +00:00 committed by GitHub
parent 0ecb2af13d
commit b2127ec2f9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 51 additions and 62 deletions

View file

@ -19,6 +19,7 @@ import java.util.Objects;
public abstract class AbstractRefCounted implements RefCounted {
public static final String ALREADY_CLOSED_MESSAGE = "already closed, can't increment ref count";
public static final String INVALID_DECREF_MESSAGE = "invalid decRef call: already closed";
private static final VarHandle VH_REFCOUNT_FIELD;
@ -63,7 +64,7 @@ public abstract class AbstractRefCounted implements RefCounted {
public final boolean decRef() {
touch();
int i = (int) VH_REFCOUNT_FIELD.getAndAdd(this, -1);
assert i > 0 : "invalid decRef call: already closed";
assert i > 0 : INVALID_DECREF_MESSAGE;
if (i == 1) {
try {
closeInternal();

View file

@ -62,4 +62,16 @@ public interface RefCounted {
* @return whether there are currently any active references to this object.
*/
boolean hasReferences();
/**
* Similar to {@link #incRef()} except that it also asserts that it managed to acquire the ref, for use in situations where it is a bug
* if all refs have been released.
*/
default void mustIncRef() {
if (tryIncRef()) {
return;
}
assert false : AbstractRefCounted.ALREADY_CLOSED_MESSAGE;
incRef(); // throws an ISE
}
}