From 583192fe91f16a4a210784f3922abbf6886f7cc8 Mon Sep 17 00:00:00 2001 From: praydog Date: Fri, 7 Mar 2025 18:45:15 -0800 Subject: [PATCH] Lua: Use atomic writes for pointer fields to match engine behavior --- src/mods/bindings/Sdk.cpp | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/mods/bindings/Sdk.cpp b/src/mods/bindings/Sdk.cpp index b8842c8a..1d779e5a 100644 --- a/src/mods/bindings/Sdk.cpp +++ b/src/mods/bindings/Sdk.cpp @@ -1014,13 +1014,22 @@ void set_data(void* data, ::sdk::RETypeDefinition* data_type, sol::object& value } REManagedObject** field = (REManagedObject**) data; - if (field != nullptr && *field != nullptr) { - utility::re_managed_object::release(*field); - } - if (new_data != nullptr) { - utility::re_managed_object::add_ref(new_data); + if (field != nullptr && *field != new_data) { + if (new_data != nullptr) { + utility::re_managed_object::add_ref(new_data); + } + + // Use a thread-safe atomic exchange. This is what Capcom does for all field assignments. + auto old = *field; + while (_InterlockedCompareExchangePointer((PVOID*)field, new_data, old) != old) { + old = *field; + } + + if (old != nullptr) { + utility::re_managed_object::release(old); + } } - *(REManagedObject**) data = new_data; + return; } }