Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
base: Fix racy crash in custom GSource implementations
When thread A is in a GSource finalizer blocked on unregister_source(), meaning its ref count is zero, thread B would be walking the Gee.Map of sources to potentially update their ready time. Thread B would be doing this with the recursive lock held, but since the loop had an owned GSource variable, it would result in each source being reffed and subsequently unreffed. This meant that the ref count would once again go from one down to zero, triggering a second call to the finalizer. This would in turn call unregister_source(), instantly acquire the recursive lock a second time, and mutate the Map that is currently being iterated. So to avoid all of this we make sure that we use an unowned variable for the source while iterating. The alternative would have been to make a copy of the Map before walking it, but that's unnecessary overhead, along with the redundant ref count updates it would entail. Co-authored-by: Håvard Sørbø <[email protected]>
- Loading branch information