Permalink
Browse files

If the node doesn't have a document (e.g., Reader), then don't bother…

… registering a gc mark function. Partly fixes #439.
  • Loading branch information...
1 parent d4184e8 commit 7f8698562b4bff5e48e545c1ffd36d9a36fe1514 @flavorjones flavorjones committed Apr 21, 2011
Showing with 11 additions and 8 deletions.
  1. +1 −0 CHANGELOG.rdoc
  2. +10 −8 ext/nokogiri/xml_node.c
View
@@ -18,6 +18,7 @@
* Add further encoding detection to HTML parser that libxml2 does not do.
* Document#remove_namespaces! now handles attributes with namespaces. #396
* XSLT::Stylesheet#transform no longer segfaults when handed a non-XML::Document. #452
+ * XML::Reader no longer segfaults when under GC pressure. #439
=== 1.4.4 / 2010-11-15
@@ -14,10 +14,7 @@ static void debug_node_dealloc(xmlNodePtr x)
static void mark(xmlNodePtr node)
{
- /* it's OK if the document isn't fully realized (as in XML::Reader). */
- /* see http://github.com/tenderlove/nokogiri/issues/closed/#issue/95 */
- if (DOC_RUBY_OBJECT_TEST(node->doc) && DOC_RUBY_OBJECT(node->doc))
- rb_gc_mark(DOC_RUBY_OBJECT(node->doc));
+ rb_gc_mark(DOC_RUBY_OBJECT(node->doc));
}
/* :nodoc: */
@@ -1241,6 +1238,8 @@ VALUE Nokogiri_wrap_xml_node(VALUE klass, xmlNodePtr node)
VALUE document = Qnil ;
VALUE node_cache = Qnil ;
VALUE rb_node = Qnil ;
+ int node_has_a_document = 0 ;
+ void (*mark_method)(xmlNodePtr) = NULL ;
assert(node);
@@ -1293,13 +1292,16 @@ VALUE Nokogiri_wrap_xml_node(VALUE klass, xmlNodePtr node)
}
}
- rb_node = Data_Wrap_Struct(klass, mark, debug_node_dealloc, node) ;
+ /* It's OK if the node doesn't have a fully-realized document (as in XML::Reader). */
+ /* see https://github.com/tenderlove/nokogiri/issues/95 */
+ /* and https://github.com/tenderlove/nokogiri/issues/439 */
+ node_has_a_document = (DOC_RUBY_OBJECT_TEST(node->doc) && DOC_RUBY_OBJECT(node->doc)) ? 1 : 0 ;
+ mark_method = node_has_a_document ? mark : NULL ;
+ rb_node = Data_Wrap_Struct(klass, mark_method, debug_node_dealloc, node) ;
node->_private = (void *)rb_node;
- if (DOC_RUBY_OBJECT_TEST(node->doc) && DOC_RUBY_OBJECT(node->doc)) {
- /* it's OK if the document isn't fully realized (as in XML::Reader). */
- /* see http://github.com/tenderlove/nokogiri/issues/closed/#issue/95 */
+ if (node_has_a_document) {
document = DOC_RUBY_OBJECT(node->doc);
node_cache = DOC_NODE_CACHE(node->doc);
rb_ary_push(node_cache, rb_node);

0 comments on commit 7f86985

Please sign in to comment.