weak pointers for Objects and delegates pointing to Objects

Thomas Kuehne thomas-dloop at kuehne.cn
Wed Oct 25 00:57:57 PDT 2006


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Who said D didn't support weak pointers?

# private import internal.gc.gcbits;
# private import internal.gc.gclinux;
# private import internal.gc.gcx;
# private import std.utf;
# private import std.gc;
# 
# class WeakPointerException : Exception{
#    this(char[] msg){
#    	super(msg);
#    }
# }
# 
# class WeakPointer(T){
#    private size_t[] hidden;
# 
#    this(T data){
#    	Object o;
#    	static if(is(T == delegate)){
#    		o = getObject(data.ptr);
#    	}else static if(is(T : Object)){
#    		o = data;
#    	}else{
#    		static assert(0, "only delegates and Objects are supported");
#    	}
# 
#    	if(!o){
#    		throw new WeakPointerException("destination not an Object");
#    	}
# 
#    	synchronized(o){
#    		hidden = new size_t[T.sizeof];
#    		ubyte[] raw = (cast(ubyte*)&data)[0 .. T.sizeof];
#    		foreach(size_t i, ubyte element; raw){
#    				hidden[i] = element;
#    		}
# 
#    		o.notifyRegister(&dead);
#    	}
#    }
# 
#    void dead(Object o){
#    	if(hidden.length && !o){
#    		static if(is(T == delegate)){
#    			(cast(Object)get().ptr).notifyUnRegister(&dead);
#    		}else{
#    			get().notifyUnRegister(&dead);
#    		}
#    	}
#    	hidden.length = 0;
#    }
# 
#    private static Object getObject(void* ptr){
#    	gc_t handle = cast(gc_t) getGCHandle();
#    	Gcx* engine = handle.gcx;
# 
#    	Pool* pool = engine.findPool(ptr);
#    	if(!pool){
#    		return null;
#    	}
# 
#    	Object o = cast(Object) ptr;
#    	if(!o){
#    		return null;
#    	}
# 
#    	ClassInfo ci = o.classinfo;
#    	if(!ci){
#    		return null;
#    	}
#    	
#    	if(ci.name.length > (1 << 12)){
#    		return null;
#    	}
#    
#    	try{
#    		std.utf.validate(ci.name);
#    	}catch{
#    		return null;
#    	}
# 
#    	return o;
#    }
# 
#    T get(){
#    	if(hidden.length < T.sizeof){
#    		throw new WeakPointerException("delegate isn't valid anymore");
#    	}
#    	T result;
#    	ubyte[] raw = (cast(ubyte*)&result)[0 .. T.sizeof];
#    	foreach(size_t i, size_t element; hidden){
#    		raw[i] = cast(ubyte)element;
#    	}
#    	return result;
#    }
# 
#    ~this(){
#    	dead(null);
#    }
# }

Usage sample:

# import std.stdio;
# 
# int main(){
#    WeakPointer!(Object) weak;
# 
#    {
#    	auto Object o = new Object();
#    	weak = new WeakPointer!(typeof(o))(o);
#    
#    	try{
#    		weak.get();
#    		writefln("WEAK: is valid");
#    	}catch{
#    		writefln("WEAK: isn't valid");
#    	}
#    }
# 
#    try{
#    	weak.get();
#    	writefln("WEAK: is valid");
#    }catch{
#    	writefln("WEAK: isn't valid");
#    }
# 
#    return 0;
# }

Don't be irritated by additional output.
http://d.puremagic.com/issues/show_bug.cgi?id=457

Thomas


-----BEGIN PGP SIGNATURE-----

iD8DBQFFPyYhLK5blCcjpWoRAgiTAJ9vsjPF0HPuYLG7lnJqSxQTZVr8iACgjWzW
4X1omJzTMbab/iEe3z3AAQc=
=n0dP
-----END PGP SIGNATURE-----



More information about the Digitalmars-d-learn mailing list