Potentially unsafe iteration in SurfaceStack (if used wrong)

Bug #1630801 reported by Chris Halse Rogers
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Mir
New
Medium
Unassigned
mir (Ubuntu)
New
Medium
Unassigned

Bug Description

RecursiveReadLocks don't exclude modification by the same thread.

This means that code like:

void ms::SurfaceStack::for_each(std::function<void(std::shared_ptr<mi::Surface> const&)> const& callback)
{
    RecursiveReadLock lg(guard);
    for (auto &surface : surfaces)
    {
        if (surface->query(mir_surface_attrib_visibility) ==
            MirSurfaceVisibility::mir_surface_visibility_exposed)
        {
            callback(surface);
        }
    }
}

is unsafe; if the callback calls into SurfaceStack::add_surface or SurfaceStack::remove_surface it will happily take a RecursiveWriteLock and mutate the surfaces vector, possibly invalidating the iterators.

Changed in mir:
importance: Undecided → Medium
Revision history for this message
Daniel van Vugt (vanvugt) wrote :

Yes; in theory. In practice it might be simpler to just document that callbacks should not modify the list.

To iterate efficiently and support callbacks that can delete entries you ideally want a callback that returns a flag to tell the loop to do the deletion (and update the iterator appropriately).

summary: - Unsafe iteration in SurfaceStack
+ Potentially unsafe iteration in SurfaceStack (if used wrong)
Revision history for this message
Michał Sawicz (saviq) wrote :

Syncing task from Mir.

Changed in mir (Ubuntu):
importance: Undecided → Medium
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.