C Extension Cleanup

J

Justin Bonnar

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
 
M

Max Lapshin

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?

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.
 
J

Justin Bonnar

Max said:
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.)
 
R

Ryan Davis

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.
 
J

Justin Bonnar

Ryan said:
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.
 
J

Joel VanderWerf

Justin said:
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?
 
J

Justin Bonnar

Joel said:
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.
 
A

ara.t.howard

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
 
N

Nobuyoshi Nakada

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.
 
J

Justin Bonnar

Nobuyoshi said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,215
Messages
2,571,113
Members
47,710
Latest member
HarleyMoli

Latest Threads

Top