On Mon, 10 Mar 2025 23:14:23 GMT, Brent Christian <bchri...@openjdk.org> wrote:

>> Please review this revision of a previously puzzling comment intending to
>> provide the rationale for a bit of non-obvious code.
>
> src/java.base/share/classes/jdk/internal/ref/CleanerImpl.java line 142:
> 
>> 140:                 // while there are registered cleanables for other 
>> objects.
>> 141:                 // If the application cleans all remaining cleanables, 
>> there
>> 142:                 // won't be any references enqueued to unblock this.  
>> Using a
> 
> I agree that calling `queue.remove()` with a timeout is the right approach.
> But I have a question:
> In the case where the Cleaner's `CleanerCleanable` has already run, and we 
> get to processing the last registered cleanable on `activeList`:
> When we do the `ref.clean()`, the `activeList` becomes empty, and we'll drop 
> out of the `while()` loop. So I'm not seeing how we would attempt another 
> `queue.remove()` in this case.
> What am I missing?

You are missing that this loop is not the only place that potentially removes
references from `activeList`. The application may also do so, when directly
cleaning (as part of a `close()` operation or the like). So the cleaner's
cleanable may be dropped, removed, and cleaned but with live entries still in
`activeList`, and this loop ends up blocked in `remove` because there's
nothing for it to do.  The application later closes all of the remaining
entries in the `activeList`, which doesn't cause anything to be enqueued on
the cleaner's queue, so the cleaner thread remains blocked in `remove`.  But
now `activeList` is empty and will never be added to, and the queue is also
empty, and the thread is blocked in `remove` with nothing (other than the
timeout) to break it out.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/23952#discussion_r1992205243

Reply via email to