Bug 1495245 - Refactor AudioDeviceMessageRunnable's use of the PluginModuleSet. r=jmathies
authorDavid Parks <dparks@mozilla.com>
Tue, 09 Oct 2018 18:02:12 -0400
changeset 496077 87fec627956b5fa5a56138ae8f4bb9e7c0e9d943
parent 496076 f4978846e9c9918b9f8a21e7b4ba1453fa2891fe
child 496078 8b19668f995cf3adcd660814fac85dff332cc697
push id9984
push userffxbld-merge
push dateMon, 15 Oct 2018 21:07:35 +0000
treeherdermozilla-beta@183d27ea8570 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjmathies
bugs1495245
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1495245 - Refactor AudioDeviceMessageRunnable's use of the PluginModuleSet. r=jmathies Changes AudioDeviceMessageRunnable to hold the AudioNotification instead of its PluginModuleSet to simplify object lifetime issues. AudioNotification is ref-counted so we can increment its ref-count during the asynchronous Runnable. Differential Revision: https://phabricator.services.mozilla.com/D7555
dom/plugins/ipc/PluginUtilsWin.cpp
--- a/dom/plugins/ipc/PluginUtilsWin.cpp
+++ b/dom/plugins/ipc/PluginUtilsWin.cpp
@@ -9,71 +9,38 @@
 #include "PluginUtilsWin.h"
 #include "PluginModuleParent.h"
 #include "mozilla/StaticMutex.h"
 
 namespace mozilla {
 namespace plugins {
 namespace PluginUtilsWin {
 
+class AudioNotification;
 typedef nsTHashtable<nsPtrHashKey<PluginModuleParent>> PluginModuleSet;
 StaticMutex sMutex;
 
 class AudioDeviceMessageRunnable : public Runnable
 {
 public:
-  explicit AudioDeviceMessageRunnable(const PluginModuleSet* aAudioNotificationSet,
-                                      NPAudioDeviceChangeDetailsIPC aChangeDetails) :
-    Runnable("AudioDeviceMessageRunnableCD")
-    , mChangeDetails(aChangeDetails)
-    , mMessageType(DEFAULT_DEVICE_CHANGED)
-    , mAudioNotificationSet(aAudioNotificationSet)
-  {}
-
-  explicit AudioDeviceMessageRunnable(const PluginModuleSet* aAudioNotificationSet,
-                                      NPAudioDeviceStateChangedIPC aDeviceState) :
-    Runnable("AudioDeviceMessageRunnableSC")
-    , mDeviceState(aDeviceState)
-    , mMessageType(DEVICE_STATE_CHANGED)
-    , mAudioNotificationSet(aAudioNotificationSet)
-  {}
+  explicit AudioDeviceMessageRunnable(AudioNotification* aAudioNotification,
+                                      NPAudioDeviceChangeDetailsIPC aChangeDetails);
 
-  NS_IMETHOD Run() override
-  {
-    StaticMutexAutoLock lock(sMutex);
-    PLUGIN_LOG_DEBUG(("Notifying %d plugins of audio device change.",
-                                            mAudioNotificationSet->Count()));
+  explicit AudioDeviceMessageRunnable(AudioNotification* aAudioNotification,
+                                      NPAudioDeviceStateChangedIPC aDeviceState);
 
-    for (auto iter = mAudioNotificationSet->ConstIter(); !iter.Done(); iter.Next()) {
-      PluginModuleParent* pluginModule = iter.Get()->GetKey();
-      bool success = false;
-      switch (mMessageType) {
-      case DEFAULT_DEVICE_CHANGED:
-        success = pluginModule->SendNPP_SetValue_NPNVaudioDeviceChangeDetails(mChangeDetails);
-        break;
-      case DEVICE_STATE_CHANGED:
-        success = pluginModule->SendNPP_SetValue_NPNVaudioDeviceStateChanged(mDeviceState);
-        break;
-      default:
-        MOZ_ASSERT_UNREACHABLE("bad AudioDeviceMessageRunnable state");
-      }
-      if(!success) {
-        return NS_ERROR_FAILURE;
-      }
-    }
-    return NS_OK;
-  }
+  NS_IMETHOD Run() override;
 
 protected:
   // The potential payloads for the message.  Type determined by mMessageType.
   NPAudioDeviceChangeDetailsIPC mChangeDetails;
   NPAudioDeviceStateChangedIPC mDeviceState;
   enum { DEFAULT_DEVICE_CHANGED, DEVICE_STATE_CHANGED } mMessageType;
 
-  const PluginModuleSet* mAudioNotificationSet;
+  AudioNotification* mAudioNotification;
 };
 
 class AudioNotification final : public IMMNotificationClient
 {
 public:
   AudioNotification() :
       mIsRegistered(false)
     , mRefCt(1)
@@ -102,17 +69,17 @@ public:
   {
     NPAudioDeviceChangeDetailsIPC changeDetails;
     changeDetails.flow = (int32_t)flow;
     changeDetails.role = (int32_t)role;
     changeDetails.defaultDevice = device_id ? std::wstring(device_id) : L"";
 
     // Make sure that plugin is notified on the main thread.
     RefPtr<AudioDeviceMessageRunnable> runnable =
-      new AudioDeviceMessageRunnable(&mAudioNotificationSet, changeDetails);
+      new AudioDeviceMessageRunnable(this, changeDetails);
     NS_DispatchToMainThread(runnable);
     return S_OK;
   }
 
   HRESULT STDMETHODCALLTYPE
   OnDeviceAdded(LPCWSTR device_id) override
   {
     return S_OK;
@@ -128,17 +95,17 @@ public:
   OnDeviceStateChanged(LPCWSTR device_id, DWORD new_state) override
   {
     NPAudioDeviceStateChangedIPC deviceStateIPC;
     deviceStateIPC.device = device_id ? std::wstring(device_id) : L"";
     deviceStateIPC.state = (uint32_t)new_state;
 
     // Make sure that plugin is notified on the main thread.
     RefPtr<AudioDeviceMessageRunnable> runnable =
-      new AudioDeviceMessageRunnable(&mAudioNotificationSet, deviceStateIPC);
+      new AudioDeviceMessageRunnable(this, deviceStateIPC);
     NS_DispatchToMainThread(runnable);
     return S_OK;
   }
 
   HRESULT STDMETHODCALLTYPE
   OnPropertyValueChanged(LPCWSTR device_id, const PROPERTYKEY key) override
   {
     return S_OK;
@@ -207,16 +174,21 @@ public:
 
   /*
    * Are any modules registered for audio notifications?
    */
   bool HasModules() {
     return !mAudioNotificationSet.IsEmpty();
   }
 
+  const PluginModuleSet* GetModuleSet() const
+  {
+    return &mAudioNotificationSet;
+  }
+
 private:
   bool mIsRegistered;   // only used to make sure that Unregister is called before destroying a Valid instance.
   LONG mRefCt;
   IMMDeviceEnumerator* mDeviceEnum;
 
   // Set of plugin modules that have registered to be notified when the audio device
   // changes.
   PluginModuleSet mAudioNotificationSet;
@@ -262,11 +234,61 @@ RegisterForAudioDeviceChanges(PluginModu
       sAudioNotification->Unregister();
       sAudioNotification->Release();
       sAudioNotification = nullptr;
     }
   }
   return NS_OK;
 }
 
+AudioDeviceMessageRunnable::AudioDeviceMessageRunnable(AudioNotification* aAudioNotification,
+                                                       NPAudioDeviceChangeDetailsIPC aChangeDetails) :
+  Runnable("AudioDeviceMessageRunnableCD")
+  , mChangeDetails(aChangeDetails)
+  , mMessageType(DEFAULT_DEVICE_CHANGED)
+  , mAudioNotification(aAudioNotification)
+{
+  // We increment the AudioNotification ref-count here -- the runnable will
+  // decrement it when it is done with us.
+  mAudioNotification->AddRef();
+}
+
+AudioDeviceMessageRunnable::AudioDeviceMessageRunnable(AudioNotification* aAudioNotification,
+                                                       NPAudioDeviceStateChangedIPC aDeviceState) :
+  Runnable("AudioDeviceMessageRunnableSC")
+  , mDeviceState(aDeviceState)
+  , mMessageType(DEVICE_STATE_CHANGED)
+  , mAudioNotification(aAudioNotification)
+{
+  // We increment the AudioNotification ref-count here -- the runnable will
+  // decrement it when it is done with us.
+  mAudioNotification->AddRef();
+}
+
+NS_IMETHODIMP
+AudioDeviceMessageRunnable::Run()
+{
+  StaticMutexAutoLock lock(sMutex);
+  PLUGIN_LOG_DEBUG(("Notifying %d plugins of audio device change.",
+                    mAudioNotification->GetModuleSet()->Count()));
+
+  bool success = true;
+  for (auto iter = mAudioNotification->GetModuleSet()->ConstIter(); !iter.Done(); iter.Next()) {
+    PluginModuleParent* pluginModule = iter.Get()->GetKey();
+    switch (mMessageType) {
+    case DEFAULT_DEVICE_CHANGED:
+      success &= pluginModule->SendNPP_SetValue_NPNVaudioDeviceChangeDetails(mChangeDetails);
+      break;
+    case DEVICE_STATE_CHANGED:
+      success &= pluginModule->SendNPP_SetValue_NPNVaudioDeviceStateChanged(mDeviceState);
+      break;
+    default:
+      MOZ_ASSERT_UNREACHABLE("bad AudioDeviceMessageRunnable state");
+    }
+  }
+  mAudioNotification->Release();
+  return success ? NS_OK : NS_ERROR_FAILURE;
+}
+
+
 }   // namespace PluginUtilsWin
 }   // namespace plugins
 }   // namespace mozilla