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