mirror of
https://github.com/f4exb/sdrangel.git
synced 2026-08-04 18:06:22 -04:00
deviceapi: Avoid iterator invalidation when clearing buddy lists
Fix cppcheck warning:
Using iterator to member container 'm_sinkBuddies' that may be invalid
clearBuddiesLists() was iterating directly over m_sourceBuddies and
m_sinkBuddies while calling removeBuddy(), which modifies the buddy
relationship lists. This could invalidate the active iterator and result in
undefined behavior.
The issue could lead to intermittent failures during buddy cleanup operations,
such as device removal, device reload, or application shutdown, depending on
container state and timing.
Iterate over copies of the buddy lists so that removing relationships does not
affect the iterators used for traversal.
Signed-off-by: Robin Getz <rgetz503@gmail.com>
This commit is contained in:
@@ -801,32 +801,35 @@ void DeviceAPI::removeBuddy(DeviceAPI* buddy)
|
||||
|
||||
void DeviceAPI::clearBuddiesLists()
|
||||
{
|
||||
auto itSource = m_sourceBuddies.begin();
|
||||
auto itSink = m_sinkBuddies.begin();
|
||||
// Make copies before iterating because removeBuddy() modifies the buddy
|
||||
// relationship lists. Iterating directly over m_sourceBuddies/m_sinkBuddies
|
||||
// could invalidate iterators while the relationships are being removed.
|
||||
auto sourceCopy = m_sourceBuddies;
|
||||
auto sinkCopy = m_sinkBuddies;
|
||||
bool leaderElected = false;
|
||||
|
||||
for (;itSource != m_sourceBuddies.end(); ++itSource)
|
||||
for (auto* buddy : sourceCopy)
|
||||
{
|
||||
if (isBuddyLeader() && !leaderElected)
|
||||
{
|
||||
(*itSource)->setBuddyLeader(true);
|
||||
buddy->setBuddyLeader(true);
|
||||
leaderElected = true;
|
||||
}
|
||||
|
||||
(*itSource)->removeBuddy(this);
|
||||
buddy->removeBuddy(this);
|
||||
}
|
||||
|
||||
m_sourceBuddies.clear();
|
||||
|
||||
for (;itSink != m_sinkBuddies.end(); ++itSink)
|
||||
for (auto* buddy : sinkCopy)
|
||||
{
|
||||
if (isBuddyLeader() && !leaderElected)
|
||||
{
|
||||
(*itSink)->setBuddyLeader(true);
|
||||
buddy->setBuddyLeader(true);
|
||||
leaderElected = true;
|
||||
}
|
||||
|
||||
(*itSink)->removeBuddy(this);
|
||||
buddy->removeBuddy(this);
|
||||
}
|
||||
|
||||
m_sinkBuddies.clear();
|
||||
|
||||
Reference in New Issue
Block a user