Prev: In-code data
Next: Watir - finding element in form
From: Eric Hodel on 25 May 2010 23:03 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 26 May 2010 03:55 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 |