ruby: fixes SEGV problem caused by GC bug at MessagePack_Unpacker_mark.

This commit is contained in:
frsyuki
2010-06-29 14:54:40 +09:00
parent 9fffa9800a
commit 34a29cd0a5
2 changed files with 14 additions and 5 deletions

View File

@@ -5,3 +5,4 @@ rescue LoadError
require File.dirname(__FILE__) + '/../lib/msgpack' require File.dirname(__FILE__) + '/../lib/msgpack'
end end
GC.stress = true

View File

@@ -287,6 +287,7 @@ static void MessagePack_Unpacker_mark(msgpack_unpack_t *mp)
unsigned int i; unsigned int i;
rb_gc_mark(mp->user.stream); rb_gc_mark(mp->user.stream);
rb_gc_mark(mp->user.streambuf); rb_gc_mark(mp->user.streambuf);
rb_gc_mark_maybe(template_data(mp));
for(i=0; i < mp->top; ++i) { for(i=0; i < mp->top; ++i) {
rb_gc_mark(mp->stack[i].obj); rb_gc_mark(mp->stack[i].obj);
rb_gc_mark_maybe(mp->stack[i].map_key); rb_gc_mark_maybe(mp->stack[i].map_key);
@@ -297,6 +298,17 @@ static VALUE MessagePack_Unpacker_alloc(VALUE klass)
{ {
VALUE obj; VALUE obj;
msgpack_unpack_t* mp = ALLOC_N(msgpack_unpack_t, 1); msgpack_unpack_t* mp = ALLOC_N(msgpack_unpack_t, 1);
// rb_gc_mark (not _maybe) is used for following member objects.
mp->user.stream = Qnil;
mp->user.streambuf = Qnil;
mp->user.finished = 0;
mp->user.offset = 0;
mp->user.buffer.size = 0;
mp->user.buffer.free = 0;
mp->user.buffer.ptr = NULL;
obj = Data_Wrap_Struct(klass, MessagePack_Unpacker_mark, obj = Data_Wrap_Struct(klass, MessagePack_Unpacker_mark,
MessagePack_Unpacker_free, mp); MessagePack_Unpacker_free, mp);
return obj; return obj;
@@ -343,14 +355,10 @@ static VALUE MessagePack_Unpacker_initialize(int argc, VALUE *argv, VALUE self)
UNPACKER(self, mp); UNPACKER(self, mp);
template_init(mp); template_init(mp);
mp->user.finished = 0;
mp->user.offset = 0;
mp->user.buffer.size = 0;
mp->user.buffer.free = 0;
mp->user.buffer.ptr = NULL;
mp->user.stream = stream; mp->user.stream = stream;
mp->user.streambuf = rb_str_buf_new(MSGPACK_UNPACKER_BUFFER_RESERVE_SIZE); mp->user.streambuf = rb_str_buf_new(MSGPACK_UNPACKER_BUFFER_RESERVE_SIZE);
mp->user.stream_append_method = append_method_of(stream); mp->user.stream_append_method = append_method_of(stream);
return self; return self;
} }