Commit b245551a authored by Joshua Haberman's avatar Joshua Haberman

Fix for race in lazy initialization of handlers.

This fixes https://github.com/protocolbuffers/protobuf/issues/6532.
parent ee4f2492
......@@ -2228,6 +2228,27 @@ static VALUE get_def_obj(VALUE _descriptor_pool, const void* ptr, VALUE klass) {
VALUE args[3] = { c_only_cookie, _descriptor_pool, key };
def = rb_class_new_instance(3, args, klass);
rb_hash_aset(descriptor_pool->def_to_descriptor, key, def);
// For message defs, we now eagerly get/create descriptors for all
// submessages. We will need these anyway to parse or serialize this
// message type. But more importantly, we must do this now so that
// add_handlers_for_message() (which calls get_msgdef_obj()) does *not*
// need to create a Ruby object or insert into a Ruby Hash. We need to
// avoid triggering GC, which can switch Ruby threads and re-enter our
// C extension from a different thread. This wreaks havoc on our state
// if we were in the middle of building handlers.
if (klass == cDescriptor) {
const upb_msgdef *m = ptr;
upb_msg_field_iter it;
for (upb_msg_field_begin(&it, m);
!upb_msg_field_done(&it);
upb_msg_field_next(&it)) {
const upb_fielddef* f = upb_msg_iter_field(&it);
if (upb_fielddef_issubmsg(f)) {
get_msgdef_obj(_descriptor_pool, upb_fielddef_msgsubdef(f));
}
}
}
}
return def;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment