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