- fixed the write barriers for the HUD message linked list.

To ensure that no broken relations occur, any change in the list must be handled by a write barrier, not just the single message that gets added.
This commit is contained in:
Christoph Oelckers 2019-06-05 20:58:59 +02:00
parent ae69abc049
commit 5b32c5b150

View file

@ -802,7 +802,9 @@ void DBaseStatusBar::CallTick()
void DBaseStatusBar::AttachMessage (DHUDMessageBase *msg, uint32_t id, int layer) void DBaseStatusBar::AttachMessage (DHUDMessageBase *msg, uint32_t id, int layer)
{ {
DHUDMessageBase *old = NULL; DHUDMessageBase *old = NULL;
TObjPtr<DHUDMessageBase *>*prev; DObject* pointing;
TObjPtr<DHUDMessageBase *>*prevp;
DHUDMessageBase* prev;
old = (id == 0 || id == 0xFFFFFFFF) ? NULL : DetachMessage (id); old = (id == 0 || id == 0xFFFFFFFF) ? NULL : DetachMessage (id);
if (old != NULL) if (old != NULL)
@ -816,20 +818,25 @@ void DBaseStatusBar::AttachMessage (DHUDMessageBase *msg, uint32_t id, int layer
layer = HUDMSGLayer_Default; layer = HUDMSGLayer_Default;
} }
prev = &Messages[layer]; pointing = this;
prevp = &Messages[layer];
prev = *prevp;
// The ID serves as a priority, where lower numbers appear in front of // The ID serves as a priority, where lower numbers appear in front of
// higher numbers. (i.e. The list is sorted in descending order, since // higher numbers. (i.e. The list is sorted in descending order, since
// it gets drawn back to front.) // it gets drawn back to front.)
while (*prev != NULL && (*prev)->SBarID > id) while (prev != NULL && prev->SBarID > id)
{ {
prev = &(*prev)->Next; pointing = prev;
prevp = &prev->Next;
prev = *prevp;
} }
msg->Next = *prev; msg->Next = prev;
msg->SBarID = id; msg->SBarID = id;
*prev = msg; *prevp = msg;
GC::WriteBarrier(msg); GC::WriteBarrier(msg, prev);
GC::WriteBarrier(pointing, msg);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -843,15 +850,18 @@ DHUDMessageBase *DBaseStatusBar::DetachMessage (DHUDMessageBase *msg)
for (size_t i = 0; i < countof(Messages); ++i) for (size_t i = 0; i < countof(Messages); ++i)
{ {
DHUDMessageBase *probe = Messages[i]; DHUDMessageBase *probe = Messages[i];
DObject* pointing = this;
TObjPtr<DHUDMessageBase *>*prev = &Messages[i]; TObjPtr<DHUDMessageBase *>*prev = &Messages[i];
while (probe && probe != msg) while (probe && probe != msg)
{ {
pointing = probe;
prev = &probe->Next; prev = &probe->Next;
probe = probe->Next; probe = probe->Next;
} }
if (probe != NULL) if (probe != NULL)
{ {
GC::WriteBarrier(pointing, probe->Next);
*prev = probe->Next; *prev = probe->Next;
probe->Next = nullptr; probe->Next = nullptr;
return probe; return probe;
@ -864,16 +874,19 @@ DHUDMessageBase *DBaseStatusBar::DetachMessage (uint32_t id)
{ {
for (size_t i = 0; i < countof(Messages); ++i) for (size_t i = 0; i < countof(Messages); ++i)
{ {
DObject* pointing = this;
DHUDMessageBase *probe = Messages[i]; DHUDMessageBase *probe = Messages[i];
TObjPtr<DHUDMessageBase *>*prev = &Messages[i]; TObjPtr<DHUDMessageBase *>*prev = &Messages[i];
while (probe && probe->SBarID != id) while (probe && probe->SBarID != id)
{ {
pointing = probe;
prev = &probe->Next; prev = &probe->Next;
probe = probe->Next; probe = probe->Next;
} }
if (probe != NULL) if (probe != NULL)
{ {
GC::WriteBarrier(pointing, probe->Next);
*prev = probe->Next; *prev = probe->Next;
probe->Next = nullptr; probe->Next = nullptr;
return probe; return probe;