resource scopes and close actions

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Feb 9 03:08:12 UTC 2022


On 09/02/2022 02:19, Michael Zucchi wrote:
> public CLContext {
>     NativeSymbol symbol;
>     ResourceScope scope;
>     MemoryAddress addr;
>
>    public static CLContext create(..., ResourceScope scope) { ... }
>
>    public CLCommandQueue createCommandQueue(, ...scope) {
>        MemoryAddress addr = clContextCreateCommandQueue(...);
>        CLCommandQueue q = CLCommandQueue.create(addr, scope);
>
>        if (scope != this.scope)
>            this.scope.addCloseAction(() -> scope.close());
>        scope.addOnCloseAction(()-> q.close());
>
>        return q;
>    }
> } 

Quick comment - if I were you I would avoid calling scope::close from 
another close action. In general you don't know if the scope you want to 
close is confined or not. If it is confined, and you call close on a 
different thread (which is possible if the main scope is managed by a 
cleaner) you have a problem.

In this case I'd keep things simple, just by verifying that the scope 
provided in createCommandQueue is the same as the expected one (or even 
omit the scope parameter from createCommandQueue).

In other words, I see value in having a scope for a CLContext, so that 
you can bring everything down when no longer needed.

I see less value (and a lot more complexity) in having to support a mix 
and match of different lifecycles.

If you need to have a long-lived object (CLContext) and have it coexist 
with many shorter-lived ones (like a CLCommandQueue), I think one 
strategy that works, and is relatively simple, is to use an implicit 
scope for CLContext, and leave that to the GC. Then you can use 
explicitly closed scopes for the short-lived entities (and maybe you can 
store a CLContext reference - or  its implicit scope - inside the 
dependent entities, to make sure the CLContext won't go away 
prematurely). This way you probably get best of both worlds:

```
CLContext clContext = CLContext.create(); // implicit scope here
try (var scope = ResourceScope.newConfinedScope) {
     CLCommandQueue queue = clContext.createCommandQueue(scope);
     ...
} // queue cleaned up here
```

Of course this is my 0.02$.

Maurizio



More information about the panama-dev mailing list