Change Deep clone in generated code to call ::protos::internal::DeepClone instead of C runtime to prevent race.

Add test that reproduces race between copy constructor and PromoteExtension.

PiperOrigin-RevId: 561144816
pull/13777/head
Protobuf Team Bot 1 year ago committed by Copybara-Service
parent fa75cd454f
commit ee817d1ad1
  1. 7
      upb/protos/protos_extension_lock_test.cc
  2. 8
      upb/protos_generator/gen_messages.cc

@ -100,6 +100,11 @@ void TestConcurrentExtensionAccess(::protos::ExtensionRegistry registry) {
::upb::Arena arena;
EXPECT_OK(::protos::Serialize(&parsed_model, arena));
};
const auto test_copy_constructor = [&] {
TestModel copy_a = parsed_model;
TestModel copy_b = parsed_model;
EXPECT_EQ(copy_a.has_str1(), copy_b.has_str1());
};
std::thread t1(test_main);
std::thread t2(test_main);
std::thread t3(test_theme);
@ -107,6 +112,7 @@ void TestConcurrentExtensionAccess(::protos::ExtensionRegistry registry) {
std::thread t5(test_theme_extension);
std::thread t6(test_theme_extension);
std::thread t7(test_serialize);
std::thread t8(test_copy_constructor);
t1.join();
t2.join();
t3.join();
@ -114,6 +120,7 @@ void TestConcurrentExtensionAccess(::protos::ExtensionRegistry registry) {
t5.join();
t6.join();
t7.join();
t8.join();
test_main();
test_theme();
test_theme_extension();

@ -366,11 +366,11 @@ void WriteMessageImplementation(
}
$0::$0(const $0& from) : $0Access() {
arena_ = owned_arena_.ptr();
msg_ = ($1*)upb_Message_DeepClone(from.msg_, &$2, arena_);
msg_ = ($1*)::protos::internal::DeepClone(from.msg_, &$2, arena_);
}
$0::$0(const CProxy& from) : $0Access() {
arena_ = owned_arena_.ptr();
msg_ = ($1*)upb_Message_DeepClone(
msg_ = ($1*)::protos::internal::DeepClone(
::protos::internal::GetInternalMsg(&from), &$2, arena_);
}
$0::$0(const Proxy& from) : $0(static_cast<const CProxy&>(from)) {}
@ -380,12 +380,12 @@ void WriteMessageImplementation(
}
$0& $0::operator=(const $3& from) {
arena_ = owned_arena_.ptr();
msg_ = ($1*)upb_Message_DeepClone(from.msg_, &$2, arena_);
msg_ = ($1*)::protos::internal::DeepClone(from.msg_, &$2, arena_);
return *this;
}
$0& $0::operator=(const CProxy& from) {
arena_ = owned_arena_.ptr();
msg_ = ($1*)upb_Message_DeepClone(
msg_ = ($1*)::protos::internal::DeepClone(
::protos::internal::GetInternalMsg(&from), &$2, arena_);
return *this;
}

Loading…
Cancel
Save