Pin frozen messages to their arena to prevent garbage collection. (#13420)

Fixes a class of flaky test failures observed only in the FFI implementation due to garbage collection in between calls to an accessors for a frozen field.

Closes #13420

COPYBARA_INTEGRATE_REVIEW=https://github.com/protocolbuffers/protobuf/pull/13420 from protocolbuffers:rub 0ea91165fb
PiperOrigin-RevId: 552602026
pull/13404/head
Jason Lunn 1 year ago committed by Copybara-Service
parent 43e1657cdf
commit 1ce24c5d0c
  1. 6
      ruby/lib/google/protobuf/ffi/internal/arena.rb
  2. 6
      ruby/lib/google/protobuf/ffi/message.rb

@ -35,6 +35,7 @@ module Google
module Protobuf
module Internal
class Arena
attr :pinned_messages
# FFI Interface methods and setup
extend ::FFI::DataConverter
@ -59,6 +60,7 @@ module Google
def initialize(pointer)
@arena = ::FFI::AutoPointer.new(pointer, Google::Protobuf::FFI.method(:free_arena))
@pinned_messages = []
end
def fuse(other_arena)
@ -67,6 +69,10 @@ module Google
raise RuntimeError.new "Unable to fuse arenas. This should never happen since Ruby does not use initial blocks"
end
end
def pin(message)
pinned_messages.push message
end
end
end

@ -80,6 +80,12 @@ module Google
instance
end
def freeze
super
@arena.pin self
self
end
def dup
duplicate = self.class.private_constructor(@arena)
mini_table = Google::Protobuf::FFI.get_mini_table(self.class.descriptor)

Loading…
Cancel
Save