www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - weak pointers for Objects and delegates pointing to Objects

reply Thomas Kuehne <thomas-dloop kuehne.cn> writes:
-----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-----
Oct 25 2006
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Thomas Kuehne wrote:

 Who said D didn't support weak pointers?

So is this "problem solved?" Are there any issues or limitations with the weak pointer code you posted? If not, Great! Weak refs were one of the last pieces of the puzzle for implementing rock-solid signals/slots from what I understood. --bb
Oct 25 2006
parent Thomas Kuehne <thomas-dloop kuehne.cn> writes:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Bill Baxter schrieb am 2006-10-26:
 Thomas Kuehne wrote:

 Who said D didn't support weak pointers?

So is this "problem solved?" Are there any issues or limitations with the weak pointer code you posted? If not, Great!

Limitation: Only objects and delegates pointing to object member functions are supported. I haven't yet looked through the GC code, but adding support for all GC allocated types ought to be possible without major changes there. Weak pointers to array elements though will most likely be impossible without major changes. Using GCC/GDC's "-finstrument-functions" should allow weak pointers for all types stored on the stack as a pure library implementation. For DMD that would require "-profile" as well as hijacking internal/trace.d. Thomas -----BEGIN PGP SIGNATURE----- iD8DBQFFQFysLK5blCcjpWoRAn+bAJsHxPYr/RNgDN76OZgyydWq0b6cSgCgkjag zP+m/bxMAq2vCt9KY4L0Nvc= =Xu4O -----END PGP SIGNATURE-----
Oct 26 2006