From: "Sean O'Dell" Date: 2003-09-12T09:55:37+09:00 Subject: Re: ruby gc hook - is there such a thing? Thomas Sondergaard wrote: >>> ~Object() { >>> rb_gc_unregister_address(_handle); >>> free(_handle); >>> } > > > I just thought of something. This .net finalizer is called asynchronously > and since ruby is not thread safe that might cause problem if ruby is > traversing the linked list that the finalizer above is removing an element > from. Tomorrow I will change the finalizer so it insteads adds the _handle > pointer to an ArrayList that I can read from the "ruby thread" when I feel > like it. A very good time to do this would be on the GC thread just before > the actual GC'ing starts. > > Is there a gc_start_hook that I can call? I imagine something like this: > > GC.gc_start_hook { > // calls rb_gc_unregister() for all the elements in the array list I > mentioned above > RubyDotNet::GcUtil.unregister_all() > } What you could do is create sort of a "global collector" object that is a C++ object which collects VALUEs and "marks" them when the GC is invoked. Create this object, and then wrap it with Data_Wrap_Struct. Register the VALUE returned as a global, so the collection never goes away so long as the Ruby environment is loaded. In your constructors, add their VALUE members to the collector. In your destructors, remove them. Block on a mutex for both actions. When your collector object's free is called, go ahead and free the collection object; Ruby is going away anyway at that point, so there's little you can do about possible dangling VALUEs in living C++ objects. When the mark function is called, block on the mutex and "mark" all the VALUEs it is holding. That will keep the VALUEs you are maintaining as members of your C++ objects around so long as the objects themselves are around. When their destructor (aka finalizer) is called, they will tell the collector object to stop marking them, and the GC will collect them eventually. All access to the list of VALUEs that the collector manipulates blocks on a single mutex, so it doesn't matter what thread your objects "die" from. Sean O'Dell