8

Im writing a Ruby extension and Im using the function Data_wrap_struct.

In order to participate in Ruby's mark-and-sweep garbage collection process, I need to define a routine to free my structure, and a routine to mark any references from my structure to other structures. I pass the classic free function to free the memory but I dont know how to use a mark function.

my structs sound like this

typedef struct
{
  int x;
  int y;
} A;

typedef struct
{
  A collection[10];
  int current;
} B;

I think that I need a mark function to mark the references in collection of struct B.

Someone can show me a example to see how a mark function works?

Matheus Moreira
  • 17,106
  • 3
  • 68
  • 107
Pioz
  • 6,051
  • 4
  • 48
  • 67

1 Answers1

6

The mark function is used to mark any Ruby objects that your C structure owns.

typedef struct {
    VALUE ruby_object;
} MyStruct;

void mark(void * p) {
    /* p is the wrapped pointer to the MyStruct instance */
    MyStruct * my_struct = (MyStruct *) p;
    rb_gc_mark(my_struct->ruby_object);
}

If the object owned by your structure isn't marked, the garbage collector could sweep it and your code may end up trying to use a finalized object.

Matheus Moreira
  • 17,106
  • 3
  • 68
  • 107
  • 1
    Do I need to mark also non-Ruby objects which are referenced by other Ruby objects? In my case I have a tree of widgets created by other Ruby classes (with references to them). – lzap Aug 20 '15 at 07:25
  • @Izap, no. The `mark` function is used to tell Ruby's garbage collector about **Ruby objects** which were created from code external to the Ruby virtual machine, such as a C extension. If you have on your hands a Ruby object which creates other native non-Ruby objects, you might want to implement a `free` function which releases resources once the Ruby object is garbage-collected. – Matheus Moreira Oct 09 '15 at 19:44