MemorySession cleanup order
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Wed Sep 14 21:58:50 UTC 2022
On 14/09/2022 22:28, Manuel Bleichenbacher wrote:
> The documentation for MemorySession.addCloseAction() states that the
> order of custom cleanup actions is unspecified. But it only hints at
> the order of custom close actions vs. closing memory segments.
>
> Is it correct that memory segments are closed first, and then the
> custom cleanup actions are executed?
>
> If so, is there a specific reason for it? It would be more useful to
> other way round.
>
> I have several cases requiring cleanup of data structures residing in
> a memory segment. It would be most natural to use custom cleanup
> actions to do so as their lifespans end at the same time. But given
> the current order, a far less elegant way is needed.
The current spec says no ordering.
In reality there is an ordering that can be relied upon (the javadoc
will likley be rectified to reflect this).
The actions added to the scope last will also be called first. Of course
the ordering is only valid for actions added within the same thread, and
if you have multiple threads adding action, other orders could be observed.
When you allocate a memory segment using a session, a cleanup action for
it is added to the session (as if calling addCloseAction), so you need
to take that into account as well.
Given all this, if you do:
```
MemorySegment.allocateNative(100, session);
session.addCloseAction(runnable);
```
I would expect the "runnable" to be executed before "free" is called on
the memory segment.
But, mind you, that alone won't help much: from the perspective of the
close action, the session attached to the segment has already been
closed, so you cannot touch the segment directly (by the same token that
protects from use after free). In other words, a session is a bit of
state that is shared by all the resources attached to that session. When
the session is closed (using the close() method), all the resources
attached to that session becomes inaccessible at once. There's no way to
add a "pre-close" action, because, if the action is pre-close, the
session is still alive, and it means that other threads have potentially
still access on the segment, and they might not know the segment is
about to be closed (so the close action would race with other accesses,
which seems a recipe for disaster).
But the cleanup action can create a copy of the segment into a fresh
segment associated with the global scope (using
MemorySegment::ofAddress), and access that instead (since it knows the
address still valid).
Maurizio
More information about the panama-dev
mailing list