[cairo-commit] rcairo/src rb_cairo_context.c, 1.24, 1.25 rb_cairo_private.c, 1.4, 1.5 rb_cairo_private.h, 1.7, 1.8 rb_cairo_surface.c, 1.38, 1.39

Kouhei Sutou commit at pdx.freedesktop.org
Mon Aug 11 05:53:35 PDT 2008


Committed by: kou

Update of /cvs/cairo/rcairo/src
In directory kemper:/tmp/cvs-serv19648/src

Modified Files:
	rb_cairo_context.c rb_cairo_private.c rb_cairo_private.h 
	rb_cairo_surface.c 
Log Message:
        * test/test_context.rb: add.

        * test/run-test.rb: don't use at_exit test runner because rcairo
        uses at_exit based GC guard mechanism.

        * src/rb_cairo_context.c: free all alive Cairo::Context before
        stop GC like Cairo::Surface.

        * src/rb_cairo_private.[ch]: abstract explicit free before stop GC
        used by Cairo::Surface.

        * src/rb_cairo_surface.c: use abstracted explicit free before stop
        GC.


Index: rb_cairo_context.c
===================================================================
RCS file: /cvs/cairo/rcairo/src/rb_cairo_context.c,v
retrieving revision 1.24
retrieving revision 1.25
diff -u -d -r1.24 -r1.25
--- rb_cairo_context.c	29 Jul 2008 01:26:54 -0000	1.24
+++ rb_cairo_context.c	11 Aug 2008 12:53:33 -0000	1.25
@@ -15,10 +15,17 @@
 #include "rb_cairo.h"
 #include "rb_cairo_private.h"
 
+#ifdef HAVE_RUBY_ST_H
+#  include <ruby/st.h>
+#else
+#  include <st.h>
+#endif
+
 VALUE rb_cCairo_Context;
 
 static ID cr_id_surface, cr_id_source;
 static ID cr_id_plus, cr_id_minus, cr_id_multi, cr_id_div;
+static cairo_user_data_key_t cr_object_holder_key;
 
 #define _SELF  (RVAL2CRCONTEXT(self))
 
@@ -62,6 +69,18 @@
   return context;
 }
 
+static rb_cairo__object_holder_t *
+cr_object_holder_new (VALUE object)
+{
+  return rb_cairo__object_holder_new (rb_cCairo_Context, object);
+}
+
+static void
+cr_object_holder_free (void *ptr)
+{
+  rb_cairo__object_holder_free (rb_cCairo_Context, ptr);
+}
+
 static void
 cr_context_free (void *ptr)
 {
@@ -92,26 +111,45 @@
 }
 
 static VALUE
-cr_initialize (VALUE self, VALUE target)
+cr_destroy (VALUE self)
 {
   cairo_t *cr;
 
-  cr = cairo_create (RVAL2CRSURFACE (target));
-  cr_check_status (cr);
-  rb_ivar_set (self, cr_id_surface, target);
-  DATA_PTR (self) = cr;
+  cr = _SELF;
+  cairo_set_user_data (cr, &cr_object_holder_key, NULL, NULL); /* needed? */
+  cairo_destroy (cr);
+
+  DATA_PTR (self) = NULL;
   return Qnil;
 }
 
 static VALUE
-cr_destroy (VALUE self)
+cr_destroy_with_destroy_check (VALUE self)
 {
-  cairo_destroy (_SELF);
-  DATA_PTR (self) = NULL;
+  if (DATA_PTR (self))
+    cr_destroy (self);
   return Qnil;
 }
 
 static VALUE
+cr_initialize (VALUE self, VALUE target)
+{
+  cairo_t *cr;
+  VALUE result = Qnil;
+
+  cr = cairo_create (RVAL2CRSURFACE (target));
+  cr_check_status (cr);
+  rb_ivar_set (self, cr_id_surface, target);
+  cairo_set_user_data (cr, &cr_object_holder_key,
+                       cr_object_holder_new(self),
+                       cr_object_holder_free);
+  DATA_PTR (self) = cr;
+  if (rb_block_given_p ())
+    result = rb_ensure (rb_yield, self, cr_destroy_with_destroy_check, self);
+  return result;
+}
+
+static VALUE
 cr_restore (VALUE self)
 {
   cairo_restore (_SELF);
@@ -1386,6 +1424,21 @@
   return self;
 }
 
+static int
+cr_destroy_all_guarded_contexts_at_end_iter (VALUE key, VALUE value, VALUE data)
+{
+  cr_destroy (key);
+  return ST_CONTINUE;
+}
+
+static void
+cr_destroy_all_guarded_contexts_at_end (VALUE data)
+{
+  rb_hash_foreach (rb_cairo__gc_guarded_objects (rb_cCairo_Context),
+                   cr_destroy_all_guarded_contexts_at_end_iter,
+                   Qnil);
+}
+
 void
 Init_cairo_context (void)
 {
@@ -1419,6 +1472,9 @@
 
   rb_define_alloc_func (rb_cCairo_Context, cr_allocate);
 
+  rb_cairo__initialize_gc_guard_holder_class (rb_cCairo_Context);
+  rb_set_end_proc(cr_destroy_all_guarded_contexts_at_end, Qnil);
+
   /* Functions for manipulating state objects */
   rb_define_method (rb_cCairo_Context, "initialize", cr_initialize, 1);
   rb_define_method (rb_cCairo_Context, "destroy", cr_destroy, 0);

Index: rb_cairo_private.c
===================================================================
RCS file: /cvs/cairo/rcairo/src/rb_cairo_private.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- rb_cairo_private.c	18 May 2007 14:07:48 -0000	1.4
+++ rb_cairo_private.c	11 Aug 2008 12:53:33 -0000	1.5
@@ -14,7 +14,9 @@
 #include "rb_cairo.h"
 #include "rb_cairo_private.h"
 
-static ID id_normalize_const_name;
+static ID cr_id_normalize_const_name;
+static ID cr_id_objects;
+static ID cr_id_dup;
 
 VALUE
 rb_cairo__float_array (double *values, unsigned count)
@@ -50,7 +52,8 @@
   char *const_name, *normalized_name;
   size_t prefix_len, normalized_name_len;
 
-  rb_normalized_name = rb_funcall (rb_mCairo, id_normalize_const_name, 1, name);
+  rb_normalized_name = rb_funcall (rb_mCairo,
+                                   cr_id_normalize_const_name, 1, name);
   normalized_name = RVAL2CSTR (rb_normalized_name);
 
   prefix_len = strlen (prefix);
@@ -70,9 +73,56 @@
   return RVAL2CBOOL (rb_obj_is_kind_of (object, klass));
 }
 
+rb_cairo__object_holder_t *
+rb_cairo__object_holder_new (VALUE klass, VALUE object)
+{
+  rb_cairo__object_holder_t *holder;
+
+  holder = ALLOC(rb_cairo__object_holder_t);
+  rb_cairo__gc_guard_add (klass, object);
+  holder->object = object;
+  return holder;
+}
+
+void
+rb_cairo__object_holder_free (VALUE klass, void *ptr)
+{
+  rb_cairo__object_holder_t *holder = ptr;
+
+  if (!NIL_P (holder->object))
+    rb_cairo__gc_guard_remove (klass, holder->object);
+
+  xfree (holder);
+}
+
+void
+rb_cairo__initialize_gc_guard_holder_class (VALUE klass)
+{
+  rb_ivar_set (klass, cr_id_objects, rb_hash_new ());
+}
+
+void
+rb_cairo__gc_guard_add (VALUE klass, VALUE object)
+{
+  rb_hash_aset (rb_ivar_get (klass, cr_id_objects), object, Qnil);
+}
+
+void
+rb_cairo__gc_guard_remove (VALUE klass, VALUE object)
+{
+  rb_hash_delete (rb_ivar_get (klass, cr_id_objects), object);
+}
+
+VALUE
+rb_cairo__gc_guarded_objects (VALUE klass)
+{
+  return rb_funcall (rb_ivar_get (klass, cr_id_objects), cr_id_dup, 0);
+}
 
 void
 Init_cairo_private (void)
 {
-  id_normalize_const_name = rb_intern ("normalize_const_name");
+  cr_id_normalize_const_name = rb_intern ("normalize_const_name");
+  cr_id_objects = rb_intern ("objects");
+  cr_id_dup = rb_intern ("dup");
 }

Index: rb_cairo_private.h
===================================================================
RCS file: /cvs/cairo/rcairo/src/rb_cairo_private.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- rb_cairo_private.h	12 Jun 2008 10:59:54 -0000	1.7
+++ rb_cairo_private.h	11 Aug 2008 12:53:33 -0000	1.8
@@ -77,4 +77,17 @@
 VALUE rb_cairo__const_get (VALUE name, const char *prefix);
 cairo_bool_t rb_cairo__is_kind_of (VALUE object, VALUE klass);
 
+typedef struct rb_cairo__object_holder {
+  VALUE object;
+} rb_cairo__object_holder_t;
+
+rb_cairo__object_holder_t *rb_cairo__object_holder_new (VALUE klass, VALUE object);
+void rb_cairo__object_holder_free (VALUE klass, void *ptr);
+
+
+void rb_cairo__initialize_gc_guard_holder_class (VALUE klass);
+void rb_cairo__gc_guard_add (VALUE klass, VALUE object);
+void rb_cairo__gc_guard_remove (VALUE klass, VALUE object);
+VALUE rb_cairo__gc_guarded_objects (VALUE klass);
+
 #endif

Index: rb_cairo_surface.c
===================================================================
RCS file: /cvs/cairo/rcairo/src/rb_cairo_surface.c,v
retrieving revision 1.38
retrieving revision 1.39
diff -u -d -r1.38 -r1.39
--- rb_cairo_surface.c	2 Aug 2008 07:49:19 -0000	1.38
+++ rb_cairo_surface.c	11 Aug 2008 12:53:33 -0000	1.39
@@ -66,8 +66,6 @@
 static ID cr_id_parse;
 static ID cr_id_size;
 static ID cr_id_set_unit;
-static ID cr_id_instances;
-static ID cr_id_dup;
 static cairo_user_data_key_t cr_closure_key;
 static cairo_user_data_key_t cr_object_holder_key;
 static cairo_user_data_key_t cr_finished_key;
@@ -301,44 +299,16 @@
   return surface;
 }
 
-static void
-add_gc_guard (VALUE self)
-{
-  rb_hash_aset (rb_ivar_get (rb_cCairo_Surface, cr_id_instances),
-                self, Qnil);
-}
-
-static void
-remove_gc_guard (VALUE self)
-{
-  rb_hash_delete (rb_ivar_get (rb_cCairo_Surface, cr_id_instances),
-                  self);
-}
-
-typedef struct cr_object_holder {
-  VALUE object;
-} cr_object_holder_t;
-
-static cr_object_holder_t *
+static rb_cairo__object_holder_t *
 cr_object_holder_new (VALUE object)
 {
-  cr_object_holder_t *holder;
-
-  holder = ALLOC(cr_object_holder_t);
-  add_gc_guard (object);
-  holder->object = object;
-  return holder;
+  return rb_cairo__object_holder_new (rb_cCairo_Surface, object);
 }
 
 static void
 cr_object_holder_free (void *ptr)
 {
-  cr_object_holder_t *holder = ptr;
-
-  if (!NIL_P (holder->object))
-    remove_gc_guard (holder->object);
-
-  xfree (holder);
+  rb_cairo__object_holder_free (rb_cCairo_Surface, ptr);
 }
 
 static void
@@ -1179,8 +1149,7 @@
 static void
 cr_finish_all_guarded_surfaces_at_end (VALUE data)
 {
-  rb_hash_foreach (rb_funcall (rb_ivar_get (rb_cCairo_Surface, cr_id_instances),
-                               cr_id_dup, 0),
+  rb_hash_foreach (rb_cairo__gc_guarded_objects (rb_cCairo_Surface),
                    cr_finish_all_guarded_surfaces_at_end_iter,
                    Qnil);
 }
@@ -1195,16 +1164,13 @@
   cr_id_parse = rb_intern ("parse");
   cr_id_size = rb_intern ("size");
   cr_id_set_unit = rb_intern ("unit=");
-  cr_id_instances = rb_intern ("instances");
-  cr_id_dup = rb_intern ("dup");
-
-  rb_set_end_proc(cr_finish_all_guarded_surfaces_at_end, Qnil);
 
   rb_cCairo_Surface =
     rb_define_class_under (rb_mCairo, "Surface", rb_cObject);
   rb_define_alloc_func (rb_cCairo_Surface, cr_surface_allocate);
 
-  rb_ivar_set (rb_cCairo_Surface, cr_id_instances, rb_hash_new ());
+  rb_cairo__initialize_gc_guard_holder_class (rb_cCairo_Surface);
+  rb_set_end_proc(cr_finish_all_guarded_surfaces_at_end, Qnil);
 
 
   rb_define_method (rb_cCairo_Surface, "create_similar",



More information about the cairo-commit mailing list