WeakRef updated to better support Tango -- and a question
Jason House
jason.james.house at gmail.com
Sat Mar 22 21:22:13 PDT 2008
I'm getting:
undefined reference to `rt_attachDisposeEvent'
undefined reference to `rt_detachDisposeEvent'
What can I do to fix that? I must admit that I didn't use the code as is, but
instead mutated it for my own purposes... Essentially, I have an AA-like object
that needs to remove the AA entry instead of invalidating a pointer.
Here's the code I used for the function prototypes:
private{
alias void delegate(Object) DisposeEvent;
extern(C) void rt_attachDisposeEvent(Object obj, DisposeEvent event);
extern(C) void rt_detachDisposeEvent(Object obj, DisposeEvent event);
}
== Quote from Bill Baxter (dnewsgroup at billbaxter.com)'s article
> This is a multi-part message in MIME format.
> --------------060908030803020302060805
> Content-Type: text/plain; charset=ISO-8859-1; format=flowed
> Content-Transfer-Encoding: 7bit
> The unittest in the previous version didn't actually work under Tango...
> oops. This version also eliminates the string alias and puts imports
> for unittests inside version(UnitTest) {...}
> Also I realized Myron Alexander had made a weak ref class a while back
> called WeakObjectReference, and posted under D.announce. The main
> difference seems to be that his version uses malloc to allocate one
> pointer, whereas I just use a size_t to hold the pointer so that the GC
> won't see it. Is there some reason why that won't cut it?
> Still hoping someone will let me add this to scrapple and/or
> tango.scrapple. Hint hint.
> --bb
> --------------060908030803020302060805
> Content-Type: text/plain;
> name="weakref.d"
> Content-Transfer-Encoding: 7bit
> Content-Disposition: inline;
> filename="weakref.d"
> /*==========================================================================
> * weakref.d
> * Written in the D Programming Language (http://www.digitalmars.com/d)
> */
> /***************************************************************************
> * Creates a weak reference to a class instance.
> *
> * A weak reference lets you hold onto a pointer to an object without
> * preventing the garbage collector from collecting it.
> * If the garbage collector collects the object then the weak pointer will
> * become 'null'. Thus one should always check a weak pointer for null
> * before doing anything that depends upon it having a value.
> *
> * Tested with:
> * DMD 1.025 / Phobos 1.025
> * DMD 1.025 / Tango 0.99.4
> *
> * Usage example:
> ---
> class Something {}
> auto a = new Something();
> auto wa = new WeakRef!(Something)(a);
> std.gc.fullCollect();
> // Reference 'a' prevents collection so wa.ptr is non-null
> assert(wa.ptr is a);
> delete a;
> // 'a' is gone now, so wa.ptr magically becomes null
> assert(wa.ptr is null);
> ---
> *
> *
> * Author: William V. Baxter III
> * Contributors:
> * Date: 21 Jan 2008
> * Copyright: (C) 2008 William Baxter
> * License: Public Domain where allowed by law, ZLIB/PNG otherwise.
> */
> //===========================================================================
> module weakref;
> version(Tango) {
> private {
> alias void delegate(Object) DisposeEvt;
> extern (C) void rt_attachDisposeEvent( Object obj, DisposeEvt evt );
> extern (C) void rt_detachDisposeEvent( Object obj, DisposeEvt evt );
> }
> }
> class WeakRef(T : Object) {
> private:
> size_t cast_ptr_;
> void unhook(Object o) {
> debug { writefln("Unhook! [%s]",o); }
> if (cast(size_t)cast(void*)o == cast_ptr_) {
> version(Tango) {
> rt_detachDisposeEvent(o, &unhook);
> } else {
> o.notifyUnRegister(&unhook);
> }
> cast_ptr_ = 0;
> }
> }
> public:
> this(T tptr) {
> cast_ptr_ = cast(size_t)cast(void*)tptr;
> version(Tango) {
> rt_attachDisposeEvent(tptr, &unhook);
> } else {
> tptr.notifyRegister(&unhook);
> }
> }
> ~this() {
> T p = ptr();
> if (p) {
> version(Tango) {
> rt_detachDisposeEvent(p, &unhook);
> } else {
> p.notifyUnRegister(&unhook);
> }
> }
> }
> T ptr() {
> return cast(T)cast(void*)cast_ptr_;
> }
> WeakRef dup() {
> return new WeakRef(ptr());
> }
> }
> version(UnitTest) {
> version(Tango) {
> import tango.core.Memory;
> alias GC.collect collect;
> } else {
> static import std.gc;
> alias std.gc.fullCollect collect;
> }
> unittest {
> class Something {
> int value;
> this(int v) { value = v; }
> ~this() { value = -1; }
> }
> WeakRef!(Something) wa;
> auto a = new Something(1);
> wa = new WeakRef!(Something)(a);
> assert(a is wa.ptr);
> collect();
> assert(a is wa.ptr);
> delete a;
> // a now gone so should be collected
> collect();
> assert(wa.ptr is null);
> }
> }
> //--- Emacs setup ---
> // Local Variables:
> // c-basic-offset: 4
> // indent-tabs-mode: nil
> // End:
> --------------060908030803020302060805--
More information about the Digitalmars-d
mailing list