Bug 1353476 - Make InputObserver refcounted. r=drno, a=dveditz
authorRandell Jesup <rjesup@jesup.org>
Tue, 04 Apr 2017 16:38:52 -0400
changeset 379436 9b81631b130a821b2af787c28e4ba02b2c5c5696
parent 379435 e081483e770de80eb78f7e77df7e06ee6ef944a3
child 379437 115218aeda4abd32f390d6410650847273e3d353
push id1419
push userjlund@mozilla.com
push dateMon, 10 Apr 2017 20:44:07 +0000
treeherdermozilla-release@5e6801b73ef6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdrno, dveditz
bugs1353476
milestone53.0
Bug 1353476 - Make InputObserver refcounted. r=drno, a=dveditz MozReview-Commit-ID: 9YULodfLBkq
dom/media/systemservices/CamerasParent.cpp
dom/media/systemservices/CamerasParent.h
--- a/dom/media/systemservices/CamerasParent.cpp
+++ b/dom/media/systemservices/CamerasParent.cpp
@@ -43,26 +43,28 @@ namespace camera {
 // - the main thread for some setups, and occassionally for video capture setup
 //   calls that don't work correctly elsewhere.
 // - the IPC thread on which PBackground is running and which receives and
 //   sends messages
 // - a thread which will execute the actual (possibly slow) camera access
 //   called "VideoCapture". On Windows this is a thread with an event loop
 //   suitable for UI access.
 
+// InputObserver is owned by CamerasParent, and it has a ref to CamerasParent
 void InputObserver::OnDeviceChange() {
   LOG((__PRETTY_FUNCTION__));
   MOZ_ASSERT(mParent);
 
+  RefPtr<InputObserver> self(this);
   RefPtr<nsIRunnable> ipc_runnable =
-    media::NewRunnableFrom([this]() -> nsresult {
-      if (mParent->IsShuttingDown()) {
+    media::NewRunnableFrom([self]() -> nsresult {
+      if (self->mParent->IsShuttingDown()) {
         return NS_ERROR_FAILURE;
       }
-      Unused << mParent->SendDeviceChange();
+      Unused << self->mParent->SendDeviceChange();
       return NS_OK;
     });
 
   nsIThread* thread = mParent->GetBackgroundThread();
   MOZ_ASSERT(thread != nullptr);
   thread->Dispatch(ipc_runnable, NS_DISPATCH_NORMAL);
 };
 
@@ -349,21 +351,21 @@ CamerasParent::SetupEngine(CaptureEngine
   config->Set<webrtc::CaptureDeviceInfo>(captureDeviceInfo);
   *engine = mozilla::camera::VideoEngine::Create(UniquePtr<const webrtc::Config>(config.release()));
 
   if (!engine->get()) {
     LOG(("VideoEngine::Create failed"));
     return false;
   }
 
-  InputObserver** observer = mObservers.AppendElement(new InputObserver(this));
+  RefPtr<InputObserver>* observer = mObservers.AppendElement(new InputObserver(this));
   auto device_info = engine->get()->GetOrCreateVideoCaptureDeviceInfo();
   MOZ_ASSERT(device_info);
   if (device_info) {
-    device_info->RegisterVideoInputFeedBack(**observer);
+    device_info->RegisterVideoInputFeedBack(*(observer->get()));
   }
 
   return true;
 }
 
 void
 CamerasParent::CloseEngines()
 {
@@ -393,19 +395,17 @@ CamerasParent::CloseEngines()
       if (device_info) {
         device_info->DeRegisterVideoInputFeedBack();
       }
       mozilla::camera::VideoEngine::Delete(engine);
       mEngines[i] = nullptr;
     }
   }
 
-  for (InputObserver* observer : mObservers) {
-    delete observer;
-  }
+  // the observers hold references to us
   mObservers.Clear();
 
   mWebRTCAlive = false;
 }
 
 VideoEngine *
 CamerasParent::EnsureInitialized(int aEngine)
 {
--- a/dom/media/systemservices/CamerasParent.h
+++ b/dom/media/systemservices/CamerasParent.h
@@ -64,23 +64,27 @@ private:
   CaptureEngine mCapEngine;
   uint32_t mStreamId;
   CamerasParent *mParent;
 };
 
 class InputObserver :  public webrtc::VideoInputFeedBack
 {
 public:
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(InputObserver)
+
   explicit InputObserver(CamerasParent* aParent)
     : mParent(aParent) {};
   virtual void OnDeviceChange();
 
   friend CamerasParent;
 
 private:
+  ~InputObserver() {}
+
   RefPtr<CamerasParent> mParent;
 };
 
 class CamerasParent :  public PCamerasParent,
                        public nsIObserver
 {
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIOBSERVER
@@ -156,17 +160,17 @@ protected:
   base::Thread* mVideoCaptureThread;
 
   // Shutdown handling
   bool mChildIsAlive;
   bool mDestroyed;
   // Above 2 are PBackground only, but this is potentially
   // read cross-thread.
   mozilla::Atomic<bool> mWebRTCAlive;
-  nsTArray<InputObserver*> mObservers;
+  nsTArray<RefPtr<InputObserver>> mObservers;
 };
 
 PCamerasParent* CreateCamerasParent();
 
 } // namespace camera
 } // namespace mozilla
 
 #endif  // mozilla_CameraParent_h