I live for the day 80% of these posts don't sound like Greek to me.  

Being pretty new to all of this though I am loving the little 'peek inside'

Ok, carry on :)

Sent from my iPhone

On Nov 24, 2012, at 10:55 AM, Robert Buck <lists / ruby-forum.com> wrote:

> For the record, if anyone else tries to write a database driver, or any
> C extension that has a graph of objects that have deallocation order
> dependencies...
> 
> If you are integrating with mark and sweep, and provide free hooks for
> your objects, be aware that at shutdown Ruby drops objects from its
> object table in allocation order (table order). This means that once it
> has called your free-hooks (defined in your calls to Data_Wrap_Struct),
> afterwards ever after YOU CANNOT / MUST NOT, ***EVER*** call
> Data_Get_Struct on a VALUE that has been visited/dropped from the Ruby
> object table. Ruby will SEGV with a very hard to diagnose issue.
> 
> Your C structs should probably do something like this:
> 
> struct hierarchical_handle
> {
>    // the hook to the real C/C++ free code, never accessed
>    // directly by Ruby GC, only via ref count decr routines
>    RUBY_DATA_FUNC free_func;
> 
>    // increment this to 1 on allocation, children inc count
>    // only free-hooks decr counts; in fact, your free-hooks
>    // could simply be atomic_dec(handle*)
>    rb_atomic_t atomic;
> 
>    // used by ref counting routines to pin C/C++ objects
>    // in memory till the last one drops its reference
>    nuodb_handle * parent_handle;
> 
>    // used to pin parents in memory via rb_gc_mark
>    VALUE parent;
> };
> 
> Like me, just steal atomic.[c|h] from Ruby. But N.B. There is a major
> bug in them, somebody in the Ruby camp used the WRONG
> GCC_ATOMIC_BUILTINS !@!!
> 
> Somebody ought to fix atomic.h, its screwed up badly.
> 
> Robert Buck wrote in post #1086203:
>> I have a graph of objects in a C extension, and as such I maintain
>> reference counts from children to parents as deallocations are order
>> dependent (see struct definition below).
>> 
>> While I run my program the reference counts match up, but when the
>> program exits, when ruby dumps its entire object table calling free on
>> every VALUE the parent's free functions are called before the children
>> as the parents were allocated first and they appear in the ruby object
>> table first (this was the whole reason for adding reference counting,
>> because otherwise order dependent deallocations in C code causes a
>> SEGV).
>> 
>> Anyways, before shutdown here are my ref counts:
>> 
>> [REFERENCE COUNT][O INCR] (child @ 00007fd6d0ddd5c0): 1 (parent @
>> 00007fd6d2538460): 2
>> 
>> n.b. 2 refs
>> 
>> And after shutdown the ref counts are "magically" different:
>> 
>> [REFERENCE COUNT][I DECR] (child @ 00007fd6d2538460): 1 (parent @
>> 0000000000000000): -10
>> 
>> n.b. -10 is just a sentinel marker, ignore that
>> n.b. 1 refs though does not match 2 above
>> 
>> The latter trace is for the root object, hence no parent. But notice the
>> root object's reference count of 1. Take a look at its reference count
>> before program termination, 2.
>> 
>> This is saying that I have a case of memory corruption on my part,
>> memory corruption on ruby's part, or my understanding of how to set up
>> graphs of interrelated objects in C extensions is seriously flawed.
>> 
>> Regarding the last option, all I am doing is maintaining a struct of:
>> 
>> struct handle
>> {
>>    RUBY_DATA_FUNC free_func;
>>    rb_atomic_t atomic;
>>    VALUE parent;
>> };
>> 
>> Would someone have an idea of how to approach this, what could possibly
>> be going on? I have been at this for three days now and I don't see any
>> bug on my part.
>> 
>> Bob
> 
> -- 
> Posted via http://www.ruby-forum.com/.
>