From: Eric Hodel on
On May 24, 2010, at 22:55, Ali Polatel wrote:
> The problem is when the parent of an object is freed, the object is
> freed automatically as well. For example when a Threads object is freed,
> all the Thread objects that belong to it are freed automatically. This
> means when the Database is freed all, or closed by the user, the
> underlying objects are freed automatically by talloc. This means an
> object may only be freed if its parent hasn't been freed yet.
>
> So far so good, to make ruby's gc play nice with this way of allocation,
> every struct that represents an object has an element VALUE parent and
> it's marked using rb_gc_mark(object->parent) in the mark phase.
>
> This problem arises when e.g. I have a database and message object and
> both of them go out of scope. Ruby-1.8 frees the message first and then
> the database but Ruby-1.9 does the opposite thus my extension blows.
>
> How can I ensure the objects are freed in order, from children to parent?

You'll need to impose the order in your free functions. You can't depend on even ruby 1.8 to free the items in the proper order by itself.
From: Robert Klemme on
2010/5/26 Eric Hodel <drbrain(a)segment7.net>:
> On May 24, 2010, at 22:55, Ali Polatel wrote:
>> The problem is when the parent of an object is freed, the object is
>> freed automatically as well. For example when a Threads object is freed,
>> all the Thread objects that belong to it are freed automatically. This
>> means when the Database is freed all, or closed by the user, the
>> underlying objects are freed automatically by talloc. This means an
>> object may only be freed if its parent hasn't been freed yet.
>>
>> So far so good, to make ruby's gc play nice with this way of allocation,
>> every struct that represents an object has an element VALUE parent and
>> it's marked using rb_gc_mark(object->parent) in the mark phase.
>>
>> This problem arises when e.g. I have a database and message object and
>> both of them go out of scope. Ruby-1.8 frees the message first and then
>> the database but Ruby-1.9 does the opposite thus my extension blows.
>>
>> How can I ensure the objects are freed in order, from children to parent?
>
> You'll need to impose the order in your free functions.  You can't depend on even ruby 1.8 to free the items in the proper order by itself.

Adding to that: relying on destruction order is a thing that typically
comes from the C++ world [1] but even there this idiom can only be
used for instances on the stack. I believe, this C++ heritage has
made people forget that memory (de)allocation and state
initialization/destruction are *two separate things*. In Ruby, this
is made obvious by the fact that classes do not define a destructor
(and a few other details, for example method Class#alloc). In other
words, you cannot rely on memory deallocation (aka GC) for state
destruction. Instead you have to do that explicitly.

In Ruby, if you want to maintain proper ordering of resource
(de)allocation you would typically use "ensure" part of blocks (either
explicitly or implicitly in a method accepting a block like File.open
with block does). Example for explicit usage:

a = create_a
begin
b = a.create_b
begin
b.use
ensure
b.release
end
ensure
a.release
end

Ali, you can find a bit more in my blog post at
http://blog.rubybestpractices.com/posts/rklemme/002_Writing_Block_Methods.html
and the other posts before and after it.

Kind regards

robert

[1] http://www.c2.com/cgi/wiki$?ResourceAllocationIsInitialization


--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

 | 
Pages: 1
Prev: In-code data
Next: Watir - finding element in form