Skip to content

Commit

Permalink
Avoid parameter reassignment, and clarify that cleanUp can process …
Browse files Browse the repository at this point in the history
…multiple references.

followup to cl/559118450

RELNOTES=n/a
PiperOrigin-RevId: 559398525
  • Loading branch information
cpovirk authored and Google Java Core Libraries committed Aug 23, 2023
1 parent 2d53d3f commit bddecdf
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 46 deletions.
66 changes: 43 additions & 23 deletions android/guava/src/com/google/common/base/internal/Finalizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -153,42 +153,62 @@ public void run() {
}

/**
* Cleans up a single reference. Catches and logs all throwables.
* Cleans up the given reference and any other references already in the queue. Catches and logs
* all throwables.
*
* @return true if the caller should continue, false if the associated FinalizableReferenceQueue
* is no longer referenced.
* @return true if the caller should continue to wait for more references to be added to the
* queue, false if the associated FinalizableReferenceQueue is no longer referenced.
*/
private boolean cleanUp(Reference<?> referenceParam) {
Reference<?> reference = referenceParam;
private boolean cleanUp(Reference<?> firstReference) {
Method finalizeReferentMethod = getFinalizeReferentMethod();
if (finalizeReferentMethod == null) {
return false;
}
do {
/*
* This is for the benefit of phantom references. Weak and soft references will have already
* been cleared by this point.
*/
reference.clear();

if (reference == frqReference) {
/*
* The client no longer has a reference to the FinalizableReferenceQueue. We can stop.
*/
if (!finalizeReference(firstReference, finalizeReferentMethod)) {
return false;
}

/*
* Loop as long as we have references available so as not to waste CPU looking up the Method
* over and over again.
*/
while (true) {
Reference<?> furtherReference = queue.poll();
if (furtherReference == null) {
return true;
}
if (!finalizeReference(furtherReference, finalizeReferentMethod)) {
return false;
}
}
}

try {
finalizeReferentMethod.invoke(reference);
} catch (Throwable t) {
logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
}
/**
* Cleans up the given reference. Catches and logs all throwables.
*
* @return true if the caller should continue to clean up references from the queue, false if the
* associated FinalizableReferenceQueue is no longer referenced.
*/
private boolean finalizeReference(Reference<?> reference, Method finalizeReferentMethod) {
/*
* This is for the benefit of phantom references. Weak and soft references will have already
* been cleared by this point.
*/
reference.clear();

if (reference == frqReference) {
/*
* Loop as long as we have references available so as not to waste CPU looking up the Method
* over and over again.
* The client no longer has a reference to the FinalizableReferenceQueue. We can stop.
*/
} while ((reference = queue.poll()) != null);
return false;
}

try {
finalizeReferentMethod.invoke(reference);
} catch (Throwable t) {
logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
}
return true;
}

Expand Down
66 changes: 43 additions & 23 deletions guava/src/com/google/common/base/internal/Finalizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -153,42 +153,62 @@ public void run() {
}

/**
* Cleans up a single reference. Catches and logs all throwables.
* Cleans up the given reference and any other references already in the queue. Catches and logs
* all throwables.
*
* @return true if the caller should continue, false if the associated FinalizableReferenceQueue
* is no longer referenced.
* @return true if the caller should continue to wait for more references to be added to the
* queue, false if the associated FinalizableReferenceQueue is no longer referenced.
*/
private boolean cleanUp(Reference<?> referenceParam) {
Reference<?> reference = referenceParam;
private boolean cleanUp(Reference<?> firstReference) {
Method finalizeReferentMethod = getFinalizeReferentMethod();
if (finalizeReferentMethod == null) {
return false;
}
do {
/*
* This is for the benefit of phantom references. Weak and soft references will have already
* been cleared by this point.
*/
reference.clear();

if (reference == frqReference) {
/*
* The client no longer has a reference to the FinalizableReferenceQueue. We can stop.
*/
if (!finalizeReference(firstReference, finalizeReferentMethod)) {
return false;
}

/*
* Loop as long as we have references available so as not to waste CPU looking up the Method
* over and over again.
*/
while (true) {
Reference<?> furtherReference = queue.poll();
if (furtherReference == null) {
return true;
}
if (!finalizeReference(furtherReference, finalizeReferentMethod)) {
return false;
}
}
}

try {
finalizeReferentMethod.invoke(reference);
} catch (Throwable t) {
logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
}
/**
* Cleans up the given reference. Catches and logs all throwables.
*
* @return true if the caller should continue to clean up references from the queue, false if the
* associated FinalizableReferenceQueue is no longer referenced.
*/
private boolean finalizeReference(Reference<?> reference, Method finalizeReferentMethod) {
/*
* This is for the benefit of phantom references. Weak and soft references will have already
* been cleared by this point.
*/
reference.clear();

if (reference == frqReference) {
/*
* Loop as long as we have references available so as not to waste CPU looking up the Method
* over and over again.
* The client no longer has a reference to the FinalizableReferenceQueue. We can stop.
*/
} while ((reference = queue.poll()) != null);
return false;
}

try {
finalizeReferentMethod.invoke(reference);
} catch (Throwable t) {
logger.log(Level.SEVERE, "Error cleaning up after reference.", t);
}
return true;
}

Expand Down

0 comments on commit bddecdf

Please sign in to comment.