Charles Mills <cmills / freeshell.org> wrote in message news:<35B7B63E-1234-11D9-873B-000A95A27A10 / freeshell.org>...
> If you were going to take a very conservative approach...
<snip>

> > VALUE ks_record(VALUE self){
> >    VALUE rbMHash, rbIHash, rbNHash, rbSHash;
> 
> Shouldn't all these hashes be volatile?

Yes, I think so.

> > static VALUE map_io_data_type(kstat_io_t k){
> >    VALUE rbHash = rb_hash_new();

> volatile rbHash?

Yes
 
> Also, ULL2NUM() (and all the 2NUM() macros) can call rb_gc() if the  
> argument is out of Fixnum range (a Bignum will be created - possibly  
> calling rb_gc() in the process).  This could cause the key argument to  
> be collected by the gc (I think).

I'd like to find out for certain.  I'll have to dig.  However, I
didn't tinker with these, and things seem to be working fine.

> > static VALUE map_named_data_type(kstat_t* ksp){
> >    VALUE rbHash;
> 
> volatile rbHash?

Yes.

<snip> 
> rb_str_new2() can call gc() (more below with backtrace).  In the first  
> case and the last case of this switch statement rb_str_new2() is called  
> twice, BEFORE rb_hash_aset() is called.  If the second call to  
> rb_str_new2() in these cases calls the rb_gc() you have problems.
> You could use a function like:
> 
> /* untested code */
> void
> hash_add_pair(VALUE hash, const char *key, const char *value)
> {
> 	volatile VALUE key_obj = rb_str_new2(key);
> 	rb_hash_aset(hash, key_obj, rb_str_new2(value));
> }

This wasn't actually necessary in testing, but it seems like a good
idea in general.  It's something I plan to do in the future. :)

> Disclaimer: these are suggestions... I am by no means an expert.
> -Charlie

Well, between you and Guy, I think it's solved - THANKS!  Now, I just
need the "Dummy's Guide to 'Volatile' in Ruby Extensions". :)

Regards,

Dan