Hi, thanks for logging this and for taking the time to put together the repro project. I’ve discussed it with the dev team, and we feel that the best way to fix this is by making a change to FObjectTrace::GetObjectId rather than just working around it within the blend stack code.
Unfortunately, since AddAnnotation replaces an existing annotation when the same object is passed, we can’t just change the return to query GetAnnotation as I’d hoped. So I think instead, we will need to add an extra lock so the code will look something like this:
auto GetObjectIdInner = [](const UObject* InObjectInner)
{
FObjectIdAnnotation Annotation = GObjectIdAnnotations.GetAnnotation(InObjectInner);
if (Annotation.Id != 0)
{
return Annotation.Id;
}
UE::TScopeLock ScopeLock(GObjectIdAllocationLock);
Annotation = GObjectIdAnnotations.GetAnnotation(InObjectInner);
if (Annotation.Id == 0)
{
Annotation.Id = AllocateInstanceId();
GObjectIdAnnotations.AddAnnotation(InObjectInner, Annotation);
}
return Annotation.Id;
};
I’m waiting to get that reviewed by the dev team. I’ll follow up once I have more info, but let me know if you have any further thoughts.
[mention removed] Did the team have any further changes to the suggested code?
Hi, yes, I ended up making some changes to avoid having to take the extra lock. I’ve attached a patch with the updated code. It adds a function to FUObjectAnnotationSparseSearchable, which will return an existing annotation if one exists when attempting to add rather than replacing it as AddAnnotation does. I haven’t committed this yet, but the final fix will at least be along these lines, if not exactly this change.
GetObjectIdConcurrencyFix_Main.zip(1.27 KB)