C Extension Cleanup

I'm writting a wrapper for a C library[1] and need to perform some
clean-up when the Ruby process exists. In my Init function, I create a
C global variable that needs to be explicitly freed after the garbage
collector has finished cleaning up all Ruby objects. How should this be
done?

-Justin

···

--
Posted via http://www.ruby-forum.com/.

As far as I understand, there is not such handler. However, You may register
global object, that will be destroyed when ruby exits. This global object
will start your cleaner.

···

On Oct 16, 2006, at 12:01 AM, Justin Bonnar wrote:

I'm writting a wrapper for a C library[1] and need to perform some
clean-up when the Ruby process exists. In my Init function, I create a
C global variable that needs to be explicitly freed after the garbage
collector has finished cleaning up all Ruby objects. How should this be
done?

Chapter 21 of the Pickaxe (2nd ed) is what you want. It covers this topic fairly well.

···

On Oct 15, 2006, at 1:01 PM, Justin Bonnar wrote:

I'm writting a wrapper for a C library[1] and need to perform some
clean-up when the Ruby process exists. In my Init function, I create a
C global variable that needs to be explicitly freed after the garbage
collector has finished cleaning up all Ruby objects. How should this be
done?

Max Lapshin wrote:

As far as I understand, there is not such handler. However, You may
register
global object, that will be destroyed when ruby exits. This global
object
will start your cleaner.

The problem is, it's not a Ruby object and I need to run some an outside
function to facilitate the clean-up. I tried creating and wrapping the
object in an anonymous class, registering the class and the instance as
global but I had segmentation fault issues (it was being freed early for
some reason.)

···

--
Posted via http://www.ruby-forum.com/\.

Ryan Davis wrote:

Chapter 21 of the Pickaxe (2nd ed) is what you want. It covers this
topic fairly well.

I'm not exposing a Ruby object though. Also, the order in which the
objects are freed when the interpreter process exits matters: if my
world object is freed before the instances, there will be a segmentation
fault. The order in which circularly referenced objects are freed at
exit seems to be undefined, so maintaining a reference for every object
won't work well.

As I said before, I tried something along the lines of:

  my_global_object *world;
  VALUE world_holder;

  void Init_extension()
  {
     world = create_world();
     world_holder = Data_Wrap_Struct(rb_cObject, 0,
free_my_global_object, world);
     rb_global_variable(world_holder);
  }

but still get segmentation faults.

···

--
Posted via http://www.ruby-forum.com/\.

Justin Bonnar wrote:

Ryan Davis wrote:

Chapter 21 of the Pickaxe (2nd ed) is what you want. It covers this
topic fairly well.

I'm not exposing a Ruby object though. Also, the order in which the objects are freed when the interpreter process exits matters: if my world object is freed before the instances, there will be a segmentation fault. The order in which circularly referenced objects are freed at exit seems to be undefined, so maintaining a reference for every object won't work well.

As I said before, I tried something along the lines of:

  my_global_object *world;
  VALUE world_holder;

  void Init_extension()
  {
     world = create_world();
     world_holder = Data_Wrap_Struct(rb_cObject, 0, free_my_global_object, world);
     rb_global_variable(world_holder);
  }

but still get segmentation faults.

Your free_my_global_object() function should be called at exit. Is it?

···

--
       vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Hi,

At Mon, 16 Oct 2006 07:17:12 +0900,
Justin Bonnar wrote in [ruby-talk:219893]:

     rb_global_variable(world_holder);

       rb_global_variable(&world_holder);

but still get segmentation faults.

Naturally.

···

--
Nobu Nakada

Joel VanderWerf wrote:

Your free_my_global_object() function should be called at exit. Is it?

It is. The problem is, it's called before freeing other wrapped
datastructures whose free funtions depend on the existance of the world
object. This results in as segmentation fault or a bus error.

I need to ensure that my free_my_global_object function isn't called
until all of my other objects have been freed.

···

--
Posted via http://www.ruby-forum.com/\.

Nobuyoshi Nakada wrote:

rb_global_variable(&world_holder);

It still faults with a Bus Error, except this time it'll wait until
finish running my test suite instead of faulting at unrelated points
half-way through.

···

--
Posted via http://www.ruby-forum.com/\.

It is. The problem is, it's called before freeing other wrapped
datastructures whose free funtions depend on the existance of the world
object.

then those objects should have a reference to it - to prevent it from being
freed by the gc...

I need to ensure that my free_my_global_object function isn't called until
all of my other objects have been freed.

it just seems like you are delcaring normal ruby gc semantics - 'free it only
when no references exist' - so the easiest thing might to to wrap it, set a
class variable to that value, and have all your objects hold references to it.

-a

···

On Mon, 16 Oct 2006, Justin Bonnar wrote:
--
my religion is very simple. my religion is kindness. -- the dalai lama