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