Resource Management... Howto?
downs
default_357-line at yahoo.de
Sat Jul 7 06:48:46 PDT 2007
Samuel Winchenbach Wrote:
> downs wrote:
> > I've been thinking about a better way to do this.
> > How about we (ab)use the GC? That is, each returned resource with the
> > same index contains a pointer to some throwaway object. This object's
> > address is stored together with the AA itself, but encoded somehow
> > (negative? xor with a constant?) so that the GC doesn't find this relation.
> > Now, whenever all resources of that type have been deleted, and the GC
> > runs, the object will not have anything obvious pointing towards it
> > anymore; thus, the GC will delete it. Before that, it will call the
> > object's destructor, which, in turn, will delete the object's entry from
> > the AA :)
> > --downs
> >
> > PS: I have no idea if that could work; also, you'd be relying on the GC
> > which the spec says _not_ to rely upon. Evil :)
> > PPS: Not guaranteed to work. Use at own risk.
>
>
> Wow, I think that might be a little advanced for me. I am on
> approximately week 2 of D. Coming from ANSI C (with a touch of C++)
> this is quite a shock for me. If you have any example code of this in
> action I would love to see it though :)
>
> Sam
Sure .. I whipped something up that seems to work.
import std.stdio, std.gc;
typedef size_t hidden;
hidden hide(Object ptr) { return cast(hidden)((cast(size_t)cast(void*)ptr)^0); } /// xor with 0 equals negation
Object show(hidden h) { return cast(Object)(h^0); }
class refcounter {
hidden ptr;
this() {
ptr=hide(new class(this) {
refcounter rc; this(refcounter r) { rc=r; }
~this() { writefln("Destructor called, telling refcounter to clean up"); rc.cleanUp; }
});
}
Object issueReference() {
return new class(show(ptr)) {
Object reftest;
this(Object obj) { reftest=obj; writefln("Reference counted object constructed"); }
~this() { writefln("Reference counted object destroyed"); }
};
}
void cleanUp() { writefln("CleanUp called. The real deal would now remove the resource from its buffer."); }
}
void main() {
auto r=new refcounter;
auto a=r.issueReference(); auto b=r.issueReference;
writefln("When calling fullCollect here, nothing will happen.");
std.gc.fullCollect;
writefln("Now delete the objects.");
delete a; delete b;
writefln("Again, fullCollect. But this time: ");
std.gc.fullCollect;
writefln("Exiting");
}
And yeah, it's a little advanced. That's because proper automated reference counting is impossible in D because of missing copy semantics - it's impossible to track the duplication of objects.
More information about the Digitalmars-d-learn
mailing list