Bug 1183925 - Part 2: Clean up the AudioChannelService shutdown; r=baku
authorEhsan Akhgari <ehsan@mozilla.com>
Tue, 14 Jul 2015 20:16:21 -0400
changeset 253110 a6d70c8955db1ce55d818976c795f45e040c781a
parent 253109 3cf4233ab1eef1d06152d5f8aa33d6e3f1b66759
child 253111 9f7b5a358a7692659af7f79829d5d31f63894d25
push id29061
push userryanvm@gmail.com
push dateThu, 16 Jul 2015 18:53:45 +0000
treeherdermozilla-central@a0f4a688433d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs1183925
milestone42.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 1183925 - Part 2: Clean up the AudioChannelService shutdown; r=baku Right now this function is called after the XPCOM component manager is shut down, so it can never remove any observers. It's better to do this work in response to xpcom-shutdown while we still have a component manager to be able to clean up after ourselves properly.
dom/audiochannel/AudioChannelService.cpp
dom/audiochannel/AudioChannelService.h
layout/build/nsLayoutStatics.cpp
--- a/dom/audiochannel/AudioChannelService.cpp
+++ b/dom/audiochannel/AudioChannelService.cpp
@@ -202,18 +202,17 @@ NS_INTERFACE_MAP_BEGIN(AudioChannelServi
   NS_INTERFACE_MAP_ENTRY(nsIAudioChannelService)
   NS_INTERFACE_MAP_ENTRY(nsIObserver)
 NS_INTERFACE_MAP_END
 
 NS_IMPL_ADDREF(AudioChannelService)
 NS_IMPL_RELEASE(AudioChannelService)
 
 AudioChannelService::AudioChannelService()
-  : mDisabled(false)
-  , mDefChannelChildID(CONTENT_PROCESS_ID_UNKNOWN)
+  : mDefChannelChildID(CONTENT_PROCESS_ID_UNKNOWN)
   , mTelephonyChannel(false)
   , mContentOrNormalChannel(false)
   , mAnyChannel(false)
 {
   if (IsParentProcess()) {
     nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
     if (obs) {
       obs->AddObserver(this, "ipc:content-shutdown", false);
@@ -233,20 +232,16 @@ AudioChannelService::AudioChannelService
 AudioChannelService::~AudioChannelService()
 {
 }
 
 void
 AudioChannelService::RegisterAudioChannelAgent(AudioChannelAgent* aAgent,
                                                AudioChannel aChannel)
 {
-  if (mDisabled) {
-    return;
-  }
-
   uint64_t windowID = aAgent->WindowID();
   AudioChannelWindow* winData = GetWindowData(windowID);
   if (!winData) {
     winData = new AudioChannelWindow(windowID);
     mWindows.AppendElement(winData);
   }
 
   MOZ_ASSERT(!winData->mAgents.Contains(aAgent));
@@ -267,20 +262,16 @@ AudioChannelService::RegisterAudioChanne
   }
 
   MaybeSendStatusUpdate();
 }
 
 void
 AudioChannelService::UnregisterAudioChannelAgent(AudioChannelAgent* aAgent)
 {
-  if (mDisabled) {
-    return;
-  }
-
   AudioChannelWindow* winData = GetWindowData(aAgent->WindowID());
   if (!winData) {
     return;
   }
 
   if (winData->mAgents.Contains(aAgent)) {
     int32_t channel = aAgent->AudioChannelType();
     uint64_t windowID = aAgent->WindowID();
@@ -461,18 +452,18 @@ AudioChannelService::AnyAudioChannelIsAc
   return false;
 }
 
 NS_IMETHODIMP
 AudioChannelService::Observe(nsISupports* aSubject, const char* aTopic,
                              const char16_t* aData)
 {
   if (!strcmp(aTopic, "xpcom-shutdown")) {
-    mDisabled = true;
     mWindows.Clear();
+    Shutdown();
   }
 
 #ifdef MOZ_WIDGET_GONK
   // To process the volume control on each audio channel according to
   // change of settings
   else if (!strcmp(aTopic, "mozsettings-changed")) {
     RootedDictionary<SettingChangeNotification> setting(nsContentUtils::RootingCxForThread());
     if (!WrappedJSToDictionary(aSubject, setting)) {
--- a/dom/audiochannel/AudioChannelService.h
+++ b/dom/audiochannel/AudioChannelService.h
@@ -38,21 +38,16 @@ public:
 
   /**
    * Returns the AudioChannelServce singleton.
    * If AudioChannelServce is not exist, create and return new one.
    * Only to be called from main thread.
    */
   static already_AddRefed<AudioChannelService> GetOrCreate();
 
-  /**
-   * Shutdown the singleton.
-   */
-  static void Shutdown();
-
   static bool IsAudioChannelMutedByDefault();
 
   /**
    * Any audio channel agent that starts playing should register itself to
    * this service, sharing the AudioChannel.
    */
   void RegisterAudioChannelAgent(AudioChannelAgent* aAgent, AudioChannel aChannel);
 
@@ -131,16 +126,21 @@ public:
 
   void ChildStatusReceived(uint64_t aChildID, bool aTelephonyChannel,
                            bool aContentOrNormalChannel, bool aAnyChannel);
 
 private:
   AudioChannelService();
   ~AudioChannelService();
 
+  /**
+   * Shutdown the singleton.
+   */
+  static void Shutdown();
+
   void MaybeSendStatusUpdate();
 
   bool ContentOrNormalChannelIsActive();
 
   /* Send the default-volume-channel-changed notification */
   void SetDefaultVolumeControlChannelInternal(int32_t aChannel,
                                               bool aVisible, uint64_t aChildID);
 
@@ -199,18 +199,16 @@ private:
   nsTObserverArray<nsAutoPtr<AudioChannelWindow>> mWindows;
 
   nsTObserverArray<nsAutoPtr<AudioChannelChildStatus>> mPlayingChildren;
 
 #ifdef MOZ_WIDGET_GONK
   nsTArray<SpeakerManagerService*>  mSpeakerManager;
 #endif
 
-  bool mDisabled;
-
   nsCOMPtr<nsIRunnable> mRunnable;
 
   uint64_t mDefChannelChildID;
 
   // These boolean are used to know if we have to send an status update to the
   // service running in the main process.
   bool mTelephonyChannel;
   bool mContentOrNormalChannel;
--- a/layout/build/nsLayoutStatics.cpp
+++ b/layout/build/nsLayoutStatics.cpp
@@ -428,18 +428,16 @@ nsLayoutStatics::Shutdown()
 
   HTMLInputElement::DestroyUploadLastDir();
 
   nsLayoutUtils::Shutdown();
 
   nsHyphenationManager::Shutdown();
   nsDOMMutationObserver::Shutdown();
 
-  AudioChannelService::Shutdown();
-
   DataStoreService::Shutdown();
 
   ContentParent::ShutDown();
 
   nsRefreshDriver::Shutdown();
 
   DisplayItemClip::Shutdown();