Crash under DisplayRefreshMonitorManager::displayWasUpdated()
https://bugs.webkit.org/show_bug.cgi?id=199808
<rdar://problem/53070144>
Reviewed by Geoffrey Garen.
Copy m_monitors before iterating over it because the calling displayLinkFired() on the
monitor may end up calling DisplayRefreshMonitorManager::displayDidRefresh() synchronously,
which removes the monitor from m_monitors.
* platform/graphics/DisplayRefreshMonitorManager.cpp:
(WebCore::DisplayRefreshMonitorManager::displayWasUpdated):
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@247459 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index 8cc638e..39fe382 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,18 @@
+2019-07-15 Chris Dumez <cdumez@apple.com>
+
+ Crash under DisplayRefreshMonitorManager::displayWasUpdated()
+ https://bugs.webkit.org/show_bug.cgi?id=199808
+ <rdar://problem/53070144>
+
+ Reviewed by Geoffrey Garen.
+
+ Copy m_monitors before iterating over it because the calling displayLinkFired() on the
+ monitor may end up calling DisplayRefreshMonitorManager::displayDidRefresh() synchronously,
+ which removes the monitor from m_monitors.
+
+ * platform/graphics/DisplayRefreshMonitorManager.cpp:
+ (WebCore::DisplayRefreshMonitorManager::displayWasUpdated):
+
2019-07-15 Yusuke Suzuki <ysuzuki@apple.com>
[JSC] Improve wasm wpt test results by fixing miscellaneous issues
diff --git a/Source/WebCore/platform/graphics/DisplayRefreshMonitorManager.cpp b/Source/WebCore/platform/graphics/DisplayRefreshMonitorManager.cpp
index 4d3cd69..699f85d 100644
--- a/Source/WebCore/platform/graphics/DisplayRefreshMonitorManager.cpp
+++ b/Source/WebCore/platform/graphics/DisplayRefreshMonitorManager.cpp
@@ -128,8 +128,10 @@
void DisplayRefreshMonitorManager::displayWasUpdated(PlatformDisplayID displayID)
{
- for (const auto& monitorWrapper : m_monitors) {
- auto& monitor = monitorWrapper.monitor;
+ Vector<RefPtr<DisplayRefreshMonitor>> monitors = WTF::map(m_monitors, [](auto& monitorWrapper) {
+ return monitorWrapper.monitor;
+ });
+ for (auto& monitor : monitors) {
if (displayID == monitor->displayID() && monitor->hasRequestedRefreshCallback())
monitor->displayLinkFired();
}