mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 05:51:20 +00:00
- 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:
parent
ae69abc049
commit
5b32c5b150
1 changed files with 20 additions and 7 deletions
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue