Bug 1353476: Make InputObserver refcounted r=drno
authorRandell Jesup <rjesup@jesup.org>
Tue, 04 Apr 2017 16:38:52 -0400
changeset 351191 71f29cc06477c41a038faa0c1d9baa9eebdf3689
parent 351190 3d46d033148b3756bf7ec3244ced7e303cc54485
child 351192 8b7e27246485369587088ec572f59f397c4bff72
push id88814
push userrjesup@wgate.com
push dateTue, 04 Apr 2017 20:39:14 +0000
treeherdermozilla-inbound@71f29cc06477 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdrno
bugs1353476
milestone55.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 1353476: Make InputObserver refcounted r=drno 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