ASSERTION FAILED: wasRemoved in WebCore::RealtimeMediaSourceCenter::removeDevicesChan...
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 May 2017 18:26:08 +0000 (18:26 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 15 May 2017 18:26:08 +0000 (18:26 +0000)
https://bugs.webkit.org/show_bug.cgi?id=171529
<rdar://problem/31945791>

Reviewed by Jer Noble.

No new tests, fixes a crash in existing tests.

* Modules/mediastream/MediaDevices.cpp:
(WebCore::MediaDevices::MediaDevices): Use a weak ptr.

* platform/mediastream/RealtimeMediaSourceCenter.cpp:
* platform/mediastream/RealtimeMediaSourceCenter.cpp:
(WebCore::observerMap):  Use a static hash map for observers because the
source center can change at runtime.
(WebCore::RealtimeMediaSourceCenter::addDevicesChangedObserver):
(WebCore::RealtimeMediaSourceCenter::removeDevicesChangedObserver):
(WebCore::RealtimeMediaSourceCenter::captureDevicesChanged):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@216866 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/Modules/mediastream/MediaDevices.cpp
Source/WebCore/Modules/mediastream/MediaDevices.h
Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.cpp
Source/WebCore/platform/mediastream/RealtimeMediaSourceCenter.h

index 7d079d3..255a6b4 100644 (file)
@@ -1,3 +1,24 @@
+2017-05-15  Eric Carlson  <eric.carlson@apple.com>
+
+        ASSERTION FAILED: wasRemoved in WebCore::RealtimeMediaSourceCenter::removeDevicesChangedObserver(DevicesChangedObserverToken)
+        https://bugs.webkit.org/show_bug.cgi?id=171529
+        <rdar://problem/31945791>
+
+        Reviewed by Jer Noble.
+
+        No new tests, fixes a crash in existing tests.
+
+        * Modules/mediastream/MediaDevices.cpp:
+        (WebCore::MediaDevices::MediaDevices): Use a weak ptr.
+
+        * platform/mediastream/RealtimeMediaSourceCenter.cpp:
+        * platform/mediastream/RealtimeMediaSourceCenter.cpp:
+        (WebCore::observerMap):  Use a static hash map for observers because the
+        source center can change at runtime.
+        (WebCore::RealtimeMediaSourceCenter::addDevicesChangedObserver):
+        (WebCore::RealtimeMediaSourceCenter::removeDevicesChangedObserver):
+        (WebCore::RealtimeMediaSourceCenter::captureDevicesChanged):
+
 2017-05-15  Brent Fulgham  <bfulgham@apple.com>
 
         [iOS WK1] Do not try to dispatch messages to subframes if their documents have not been constructed yet.
index 055095d..cfda721 100644 (file)
@@ -48,8 +48,12 @@ namespace WebCore {
 inline MediaDevices::MediaDevices(Document& document)
     : ContextDestructionObserver(&document)
     , m_scheduledEventTimer(*this, &MediaDevices::scheduledEventTimerFired)
+    , m_weakPtrFactory(this)
 {
-    m_deviceChangedToken = RealtimeMediaSourceCenter::singleton().addDevicesChangedObserver([this]() {
+    m_deviceChangedToken = RealtimeMediaSourceCenter::singleton().addDevicesChangedObserver([weakThis = createWeakPtr(), this]() {
+
+        if (!weakThis)
+            return;
 
         // FIXME: We should only dispatch an event if the user has been granted access to the type of
         // device that was added or removed.
index fb5a11c..9f30c3e 100644 (file)
@@ -39,6 +39,7 @@
 #include "MediaTrackConstraints.h"
 #include "RealtimeMediaSourceCenter.h"
 #include "Timer.h"
+#include <wtf/WeakPtr.h>
 
 namespace WebCore {
 
@@ -81,8 +82,11 @@ private:
     void refEventTarget() override { ref(); }
     void derefEventTarget() override { deref(); }
 
+    WeakPtr<MediaDevices> createWeakPtr() { return m_weakPtrFactory.createWeakPtr(); }
+
     Timer m_scheduledEventTimer;
     std::optional<RealtimeMediaSourceCenter::DevicesChangedObserverToken> m_deviceChangedToken;
+    WeakPtrFactory<MediaDevices> m_weakPtrFactory;
 };
 
 } // namespace WebCore
index cc33851..78d2f81 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2011 Ericsson AB. All rights reserved.
  * Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -45,6 +46,12 @@ static RealtimeMediaSourceCenter*& mediaStreamCenterOverride()
     return override;
 }
 
+static HashMap<unsigned, std::function<void()>>& observerMap()
+{
+    static NeverDestroyed<HashMap<unsigned, std::function<void()>>> map;
+    return map;
+}
+
 RealtimeMediaSourceCenter& RealtimeMediaSourceCenter::singleton()
 {
     RealtimeMediaSourceCenter* override = mediaStreamCenterOverride();
@@ -181,20 +188,21 @@ ExceptionOr<void> RealtimeMediaSourceCenter::setDeviceEnabled(const String&, boo
 RealtimeMediaSourceCenter::DevicesChangedObserverToken RealtimeMediaSourceCenter::addDevicesChangedObserver(std::function<void()>&& observer)
 {
     static DevicesChangedObserverToken nextToken = 0;
-    m_devicesChangedObservers.set(++nextToken, WTFMove(observer));
+    observerMap().set(++nextToken, WTFMove(observer));
     return nextToken;
 }
 
 void RealtimeMediaSourceCenter::removeDevicesChangedObserver(DevicesChangedObserverToken token)
 {
-    bool wasRemoved = m_devicesChangedObservers.remove(token);
+    bool wasRemoved = observerMap().remove(token);
     ASSERT_UNUSED(wasRemoved, wasRemoved);
 }
 
 void RealtimeMediaSourceCenter::captureDevicesChanged()
 {
-    auto callbacks = m_devicesChangedObservers;
-    for (auto it : callbacks)
+    // Copy the hash map because the observer callback may call back in and modify the map.
+    auto callbacks = observerMap();
+    for (auto& it : callbacks)
         it.value();
 }
 
index 44d547d..57d7132 100644 (file)
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2011 Ericsson AB. All rights reserved.
  * Copyright (C) 2012 Google Inc. All rights reserved.
+ * Copyright (C) 2013-2016 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -108,8 +109,6 @@ protected:
 
     CaptureDeviceManager* m_audioCaptureDeviceManager { nullptr };
     CaptureDeviceManager* m_videoCaptureDeviceManager { nullptr };
-
-    HashMap<unsigned, std::function<void()>> m_devicesChangedObservers;
 };
 
 } // namespace WebCore