Sean Kelly wrote:
Georg Wrede wrote:
Sean Kelly wrote:
dsimcha wrote:
1. It is often nice to be able to create a single object that
works with both GC and deterministic memory management. The
idea is that, if delete is called manually, all sub-objects
would be freed deterministically, but the object could still
safely be GC'd. Since the destructor called by the GC can't
reference sub-objects, would it be feasible to have two
destructors for each class, one that is called when delete is
invoked manually and another that is called by the GC?
You can do this today with both Druntime on D 2.0 and Tango on D 1.0,
though it isn't the most performant approach. The code would look
something like this:
import core.runtime;
interface Disposable
{
void dispose();
}
bool handler( Object o )
{
auto d = cast(Disposable) o;
if( d !is null )
{
d.dispose();
return false;
}
return true;
}
static this()
{
Runtime.collectHandler = &handler;
}
If you return false from your collectHandler then the runtime won't
call the object's dtor.
Err, if one has an object that needs deterministic destruction, then
one calls it (with say myDelete()) to have it release its resources.
Until then, of course, it shouldn't get collected. But in any case it
won't, because we obviously have a handler to it because we still
haven't decided to destruct it. So I assume there's something I don't
understand here.
After we're done with destructing (as in having called myDelete()),
then we "delete the object", or let it go out of scope. Then it
becomes eligible for disposal. So, what's the relevance of Disposable
here?
The collectHandler will only be called if an object is collected by the
GC, not if it's explicitly deleted. So you could write the dtor in a
way that assumes all referenced subobjects are still valid and use
dispose for cleanup of garbage collected instances only. To me that
sounded fairly close to what dsimcha was asking for.
Dsimcha wrote "Since the destructor called by the GC can't reference
sub-objects", I got into thinking that we'd then need a myDestructor.
But
delete myobject;
calls ~this() in myobject, as does the GC, as does program exit.
I also tested, and the referenced other objects did get deleted. No
problem. That implies releasing other resources works, by simply having
such release code in ~this() for the object.
I found no difference in calling delete or letting the GC do it. So,
originally dsimcha's problem was imagined?