Index: content/renderer/media/renderer_webmediaplayer_delegate.cc |
diff --git a/content/renderer/media/renderer_webmediaplayer_delegate.cc b/content/renderer/media/renderer_webmediaplayer_delegate.cc |
index 2ae2b8bd2838c03dae8e2d1218572e4947b200c1..9660d423724adbd6f0294160d30c869a40ab6399 100644 |
--- a/content/renderer/media/renderer_webmediaplayer_delegate.cc |
+++ b/content/renderer/media/renderer_webmediaplayer_delegate.cc |
@@ -220,9 +220,16 @@ void RendererWebMediaPlayerDelegate::RemoveIdleDelegate(int delegate_id) { |
void RendererWebMediaPlayerDelegate::CleanupIdleDelegates( |
base::TimeDelta timeout) { |
+ // Drop reentrant cleanups which can occur during forced suspension when the |
+ // number of idle delegates is too high for a given device. |
+ if (idle_cleanup_running_) |
+ return; |
+ |
// Iterate over the delegates and suspend the idle ones. Note: The call to |
- // OnHidden() can trigger calls into RemoveIdleDelegate(), so for iterator |
- // validity we set |idle_cleanup_running_| to true and defer deletions. |
+ // OnSuspendRequested() can trigger calls into RemoveIdleDelegate(), so for |
+ // iterator validity we set |idle_cleanup_running_| to true and defer |
+ // deletions. |
+ DCHECK(!idle_cleanup_running_); |
base::AutoReset<bool> scoper(&idle_cleanup_running_, true); |
const base::TimeTicks now = tick_clock_->NowTicks(); |
for (auto& idle_delegate_entry : idle_delegate_map_) { |