[yast-commit] r66205 - in /trunk/ruby-bindings/src/ruby: Y2RubyTypeConv.cc YRuby.cc YRuby.h
Author: mvidner Date: Mon Oct 3 17:23:37 2011 New Revision: 66205 URL: http://svn.opensuse.org/viewcvs/yast?rev=66205&view=rev Log: Assist mark+sweep garbage collection by marking values referenced from YCP. Countess Reference marries Mark Sweep. Modified: trunk/ruby-bindings/src/ruby/Y2RubyTypeConv.cc trunk/ruby-bindings/src/ruby/YRuby.cc trunk/ruby-bindings/src/ruby/YRuby.h Modified: trunk/ruby-bindings/src/ruby/Y2RubyTypeConv.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/ruby-bindings/src/ruby/Y2RubyTypeConv.cc?rev=66205&r1=66204&r2=66205&view=diff ============================================================================== --- trunk/ruby-bindings/src/ruby/Y2RubyTypeConv.cc (original) +++ trunk/ruby-bindings/src/ruby/Y2RubyTypeConv.cc Mon Oct 3 17:23:37 2011 @@ -46,6 +46,9 @@ #include <ycp/YCPExternal.h> #include <ycp/Import.h> +#include <cassert> + +#include "YRuby.h" #include "Y2RubyTypePath.h" #include "Y2RubyTypeTerm.h" @@ -98,9 +101,31 @@ #define YCP_EXTERNAL_MAGIC "Ruby object" +static void ycpexternal_finalizer(void * value_v, string /*magic*/) +{ + VALUE value = (VALUE)value_v; + + YRuby::refcount_map_t& vrby = YRuby::yRuby()->value_references_from_ycp; + YRuby::refcount_map_t::iterator it = vrby.find(value); + assert(it != vrby.end()); + + int & count = it->second; + --count; + y2internal("Refcount of value %ld decremented to %d", value, count); + assert(count >= 0); + + if (count == 0) { + vrby.erase(it); + } +} + static YCPExternal rbobject_2_ycpexternal( VALUE value ) { - YCPExternal ex((void*) value, string(YCP_EXTERNAL_MAGIC), NULL); + YCPExternal ex((void*) value, string(YCP_EXTERNAL_MAGIC), ycpexternal_finalizer); + + // defaults to zero, ok + int count = ++YRuby::yRuby()->value_references_from_ycp[value]; + y2internal("Refcount of value %ld incremented to %d", value, count); return ex; } Modified: trunk/ruby-bindings/src/ruby/YRuby.cc URL: http://svn.opensuse.org/viewcvs/yast/trunk/ruby-bindings/src/ruby/YRuby.cc?rev=66205&r1=66204&r2=66205&view=diff ============================================================================== --- trunk/ruby-bindings/src/ruby/YRuby.cc (original) +++ trunk/ruby-bindings/src/ruby/YRuby.cc Mon Oct 3 17:23:37 2011 @@ -82,6 +82,32 @@ //ruby_options(argc - 1, ++argv); ruby_script("yast"); ruby_init_loadpath(); + + VALUE ycp_references = Data_Wrap_Struct(rb_cObject, gc_mark, gc_free, & value_references_from_ycp); + rb_global_variable(&ycp_references); +} + +void YRuby::gc_mark(void *object) +{ + refcount_map_t * vrby = (refcount_map_t *) object; + + y2internal("mark: map size is %u", vrby->size()); + refcount_map_t::iterator + b = vrby->begin(), + e = vrby->end(), + it; + for (it = b; it != e; ++it) { + y2internal("marking: value %ld refcount %d", it->first, it->second); + rb_gc_mark(it->first); + } +} + +void YRuby::gc_free(void *object) +{ + refcount_map_t * vrby = (refcount_map_t *) object; + + y2internal("free: map size is %u", vrby->size()); + y2internal("should happen quite last or we are in trouble FIXME"); } YRuby::~YRuby() Modified: trunk/ruby-bindings/src/ruby/YRuby.h URL: http://svn.opensuse.org/viewcvs/yast/trunk/ruby-bindings/src/ruby/YRuby.h?rev=66205&r1=66204&r2=66205&view=diff ============================================================================== --- trunk/ruby-bindings/src/ruby/YRuby.h (original) +++ trunk/ruby-bindings/src/ruby/YRuby.h Mon Oct 3 17:23:37 2011 @@ -97,11 +97,23 @@ **/ YCPValue callInner (string module, string function, bool method, YCPList argList, constTypePtr wanted_result_type); + /** + * Ruby VALUEs do not have a reference count like YCP or Perl. + * To protect them from being garbage-collected, they must be marked + * via ruby_gc_mark + * + * A set is not enough: one VALUE can be referenced by multiple + * YCPValueReps + */ + typedef std::map<VALUE, int> refcount_map_t; -protected: - +private: + static void gc_mark(void *object); + static void gc_free(void *object); + public: static YRuby * _yRuby; + refcount_map_t value_references_from_ycp; }; #endif // YRuby_h -- To unsubscribe, e-mail: yast-commit+unsubscribe@opensuse.org For additional commands, e-mail: yast-commit+help@opensuse.org
participants (1)
-
mvidner@svn2.opensuse.org