How can I signal a master object that a resource handle is no longer used, from within the resource class's destructor?

Steven Schveighoffer schveiguy at gmail.com
Thu Jun 26 16:40:10 UTC 2025


On Tuesday, 24 June 2025 at 08:48:16 UTC, realhet wrote:

> This is working in a normal use case: I create a Texture class 
> insance, I store it's pointer and later when I press a key, I 
> release the class pointer.
>
> But when I do not store the class pointer: `new Texture(...);` 
> It just enters into a dead stall right after the first GC call.
>
> Maybe it is because inside MSQueue.put() there is a 
> synchronized{} clause and when the GC runs every thread is 
> stopped?

Finalizers are run with the world resumed. But if you can learn 
where it's hanging, it can give more information.

But there is another problem with your synchronization. A 
`synchronized` statement needs a mutex to use for protection. 
When you don't give it one, it just makes one for each 
`synchronized` statement implicitly.

Therefore, a call to `fetch` is not synchronized with a call to 
`put`. Only calls to `fetch` are synchronized with each other, 
and calls to `put` are synchronized with each other.

>
> Maybe it because there are additional memory allocation inside 
> MSQueue.put()?

If you allocate inside a finalizer, the system should throw an 
error, not hang. But yes, you are allocating in that put 
function, that is not allowed. What *may* be happening is that 
the error is thrown in a non-main thread, and now the process is 
invalid.

What about using C malloc to allocate your link nodes? Surely the 
queue can be manually managed for memory.

> What's the best practice to do this automatic resource 
> deallocation problem?
>
> Manual deallocation is not a solution for this, because the 
> meaning of this is to avoid manual deallocation, and the human 
> errors that comes with that, in the first place. ;)

Can you post the usage of the item? And what is 
`TB.createHandleAndSetData(fmt, data);`? Is this a C library 
function? What does it do?

You are storing an *int* which means there is no reference to 
anything that is stored on behalf of that int. In particular, I'm 
suspicious of the `data` parameter.

In a GC finalizer, you should be able to access and clean up 
resources allocated outside the GC. You cannot access any 
resources allocated with the GC (unless they are pinned).

Is there a reason you don't want to immediately clean up the 
resource in the destructor?

-Steve


More information about the Digitalmars-d-learn mailing list