[iOS] Avoid WebStateList reentrancy from GridViewController.
There are relatively frequent crashes (see bug) originating from GridViewController inducing reentrancy into WebStateList. This happens when a state-mutating method (in this case, ActivateWebStateAt()) is called on WebStateList while it is still handling a different state- mutating method call. The initial method call triggers observer methods, then the observer method (usually very indirectly) calls another state- mutating method. Specifically for this bug, this sequence of events happens: 1) Something causes a new tab to be inserted (there are many ways to do this). 2) The tab insertion is observed by TabGridMediator, which calls the -insertItem:atIndex:selectedItemID: consumer method. 3) The consumer (the GridViewController) eventually calls [UICollectionView performBatchUpdates:completion:]. 4) Roughly 24 stack frames of UIKit calls happen. 5) [UICollectionViewDelegate -shouldSelectItemAtIndexPath:] is called. 6) GridViewController subsequently calls (eventually) [TabGridMediator -selectItemWithID], which calls ActivateWebStateAt(). I don't have repro steps, so I haven't seen a crash with the symbols for the UIKit stack frames in step (4), so I don't know what the collection view is doing to make this happen. The collection view docs say that -shouldSelectItemAtIndexPath: should *only* be called when the user taps on a cell, and never when the cell is programmatically selected. But it looks like that's still what's happening. Absent repro steps, this CL puts two layers of speculative fixes. First, TabGridMediator's selectItemWithID: method adds several early- return possibilities; it will now early-return if the selected item is already selected, and it will early-return if the web state list is locked for mutation. Note that it's unclear what will happen in this case, since the activation event might be triggering the tab being opened. Second, GridViewController sets an 'updating' flag while the collection view batch update is in progress, and doesn't handle cell selection while this flag is set. Either one of these should fix the crash, but since there aren't repro steps, I've added both. Bug: 1134663 Change-Id: Ia838a5da9b763dbe8b82acc69957327d96259261 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2614432 Commit-Queue: Mark Cogan <marq@chromium.org> Reviewed-by:Mark Cogan <marq@chromium.org> Reviewed-by:
Sylvain Defresne <sdefresne@chromium.org> Cr-Commit-Position: refs/heads/master@{#841560}
Showing
Please register or sign in to comment