On 6/27/17 9:25 AM, Guillaume Piolat wrote:
On Tuesday, 27 June 2017 at 13:11:10 UTC, Steven Schveighoffer wrote:
But I would use a close method, and not destroy(obj). The reason is
because often times, you have wrapper types around your socket type,
and just one extra level of indirection means the destructor cannot be
used to clean up the socket (you are not allowed to access
GC-allocated resources in a destructor).
All destructor restrictions do not apply when it's not called by the GC.
There really are two categories of destructors: called by the GC and
called deterministically. Their usage should not overlap.
Yes, Tango solved this by having a separate "finalize()" method. I wish
we had something like this.
My reasoning went with the following:
1 - "I should have close() methods so that I don't rely on the GC, and
the GC is calling ~this from the wrong thread etc, not everything can be
released in this context (eg: OpenGL objects should be released from one
thread only). Close methods will call close methods of "owned" objects."
I hadn't realized this, that is a good point. However, not all resources
are restricted this much.
That's how the GC-proof resource class came to existence, after many
destruction bugs, and it let's you use the GC as a detector for
non-deterministic destruction. I miss it in @nogc :)
https://p0nce.github.io/d-idioms/#GC-proof-resource-class
There are definitely better ways to do this than trying to allocate and
catching an error. The GC knows the GC is running, use that mechanism
instead :)
Remember years ago when Alexandrescu suggested the GC shouldn't call
heap destructors? That's what we get for having said no at the time.
No, the issue is that there isn't a separate call for destruction and
GC. I think we should add this.
The GC still needs to call something to clean up non-memory resources,
but having a call to use when cleaning up deterministically can make
resource management more efficient (even memory resource management).
-Steve
-Steve