|
@@ -1,324 +0,0 @@
|
|
-# HG changeset patch
|
|
|
|
-# User Paul Adenot <paul@paul.cx>
|
|
|
|
-# Date 1519403727 -3600
|
|
|
|
-# Node ID ee3fdd1fb7beb534833a6677733a8fec44e05ec9
|
|
|
|
-# Parent 1c511c19be41dbb119881638292d56b3ea43f4f3
|
|
|
|
-Bug 1426129 - Take a reference to `this` when calling methods asynchronously in CameraChild.cpp r=pehrsons
|
|
|
|
-
|
|
|
|
-diff --git a/dom/media/systemservices/CamerasChild.cpp b/dom/media/systemservices/CamerasChild.cpp
|
|
|
|
---- a/dom/media/systemservices/CamerasChild.cpp
|
|
|
|
-+++ b/dom/media/systemservices/CamerasChild.cpp
|
|
|
|
-@@ -29,17 +29,19 @@ mozilla::LazyLogModule gCamerasChildLog(
|
|
|
|
-
|
|
|
|
- namespace mozilla {
|
|
|
|
- namespace camera {
|
|
|
|
-
|
|
|
|
- CamerasSingleton::CamerasSingleton()
|
|
|
|
- : mCamerasMutex("CamerasSingleton::mCamerasMutex"),
|
|
|
|
- mCameras(nullptr),
|
|
|
|
- mCamerasChildThread(nullptr),
|
|
|
|
-- mFakeDeviceChangeEventThread(nullptr) {
|
|
|
|
-+ mFakeDeviceChangeEventThread(nullptr),
|
|
|
|
-+ mInShutdown(false)
|
|
|
|
-+{
|
|
|
|
- LOG(("CamerasSingleton: %p", this));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- CamerasSingleton::~CamerasSingleton() {
|
|
|
|
- LOG(("~CamerasSingleton: %p", this));
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- class FakeOnDeviceChangeEventRunnable : public Runnable
|
|
|
|
-@@ -286,33 +288,33 @@ CamerasChild::DispatchToParent(nsIRunnab
|
|
|
|
- int
|
|
|
|
- CamerasChild::NumberOfCapabilities(CaptureEngine aCapEngine,
|
|
|
|
- const char* deviceUniqueIdUTF8)
|
|
|
|
- {
|
|
|
|
- LOG((__PRETTY_FUNCTION__));
|
|
|
|
- LOG(("NumberOfCapabilities for %s", deviceUniqueIdUTF8));
|
|
|
|
- nsCString unique_id(deviceUniqueIdUTF8);
|
|
|
|
- nsCOMPtr<nsIRunnable> runnable =
|
|
|
|
-- mozilla::NewNonOwningRunnableMethod<CaptureEngine, nsCString>(
|
|
|
|
-+ mozilla::NewRunnableMethod<CaptureEngine, nsCString>(
|
|
|
|
- "camera::PCamerasChild::SendNumberOfCapabilities",
|
|
|
|
- this,
|
|
|
|
- &CamerasChild::SendNumberOfCapabilities,
|
|
|
|
- aCapEngine,
|
|
|
|
- unique_id);
|
|
|
|
- LockAndDispatch<> dispatcher(this, __func__, runnable, 0, mReplyInteger);
|
|
|
|
- LOG(("Capture capability count: %d", dispatcher.ReturnValue()));
|
|
|
|
- return dispatcher.ReturnValue();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- int
|
|
|
|
- CamerasChild::NumberOfCaptureDevices(CaptureEngine aCapEngine)
|
|
|
|
- {
|
|
|
|
- LOG((__PRETTY_FUNCTION__));
|
|
|
|
- nsCOMPtr<nsIRunnable> runnable =
|
|
|
|
-- mozilla::NewNonOwningRunnableMethod<CaptureEngine>(
|
|
|
|
-+ mozilla::NewRunnableMethod<CaptureEngine>(
|
|
|
|
- "camera::PCamerasChild::SendNumberOfCaptureDevices",
|
|
|
|
- this,
|
|
|
|
- &CamerasChild::SendNumberOfCaptureDevices,
|
|
|
|
- aCapEngine);
|
|
|
|
- LockAndDispatch<> dispatcher(this, __func__, runnable, 0, mReplyInteger);
|
|
|
|
- LOG(("Capture Devices: %d", dispatcher.ReturnValue()));
|
|
|
|
- return dispatcher.ReturnValue();
|
|
|
|
- }
|
|
|
|
-@@ -329,17 +331,17 @@ CamerasChild::RecvReplyNumberOfCaptureDe
|
|
|
|
- return IPC_OK();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- int
|
|
|
|
- CamerasChild::EnsureInitialized(CaptureEngine aCapEngine)
|
|
|
|
- {
|
|
|
|
- LOG((__PRETTY_FUNCTION__));
|
|
|
|
- nsCOMPtr<nsIRunnable> runnable =
|
|
|
|
-- mozilla::NewNonOwningRunnableMethod<CaptureEngine>(
|
|
|
|
-+ mozilla::NewRunnableMethod<CaptureEngine>(
|
|
|
|
- "camera::PCamerasChild::SendEnsureInitialized",
|
|
|
|
- this,
|
|
|
|
- &CamerasChild::SendEnsureInitialized,
|
|
|
|
- aCapEngine);
|
|
|
|
- LockAndDispatch<> dispatcher(this, __func__, runnable, 0, mReplyInteger);
|
|
|
|
- LOG(("Capture Devices: %d", dispatcher.ReturnValue()));
|
|
|
|
- return dispatcher.ReturnValue();
|
|
|
|
- }
|
|
|
|
-@@ -348,17 +350,17 @@ int
|
|
|
|
- CamerasChild::GetCaptureCapability(CaptureEngine aCapEngine,
|
|
|
|
- const char* unique_idUTF8,
|
|
|
|
- const unsigned int capability_number,
|
|
|
|
- webrtc::VideoCaptureCapability& capability)
|
|
|
|
- {
|
|
|
|
- LOG(("GetCaptureCapability: %s %d", unique_idUTF8, capability_number));
|
|
|
|
- nsCString unique_id(unique_idUTF8);
|
|
|
|
- nsCOMPtr<nsIRunnable> runnable =
|
|
|
|
-- mozilla::NewNonOwningRunnableMethod<CaptureEngine, nsCString, unsigned int>(
|
|
|
|
-+ mozilla::NewRunnableMethod<CaptureEngine, nsCString, unsigned int>(
|
|
|
|
- "camera::PCamerasChild::SendGetCaptureCapability",
|
|
|
|
- this,
|
|
|
|
- &CamerasChild::SendGetCaptureCapability,
|
|
|
|
- aCapEngine,
|
|
|
|
- unique_id,
|
|
|
|
- capability_number);
|
|
|
|
- LockAndDispatch<> dispatcher(this, __func__, runnable, -1, mZero);
|
|
|
|
- if (dispatcher.Success()) {
|
|
|
|
-@@ -390,17 +392,17 @@ CamerasChild::GetCaptureDevice(CaptureEn
|
|
|
|
- unsigned int list_number, char* device_nameUTF8,
|
|
|
|
- const unsigned int device_nameUTF8Length,
|
|
|
|
- char* unique_idUTF8,
|
|
|
|
- const unsigned int unique_idUTF8Length,
|
|
|
|
- bool* scary)
|
|
|
|
- {
|
|
|
|
- LOG((__PRETTY_FUNCTION__));
|
|
|
|
- nsCOMPtr<nsIRunnable> runnable =
|
|
|
|
-- mozilla::NewNonOwningRunnableMethod<CaptureEngine, unsigned int>(
|
|
|
|
-+ mozilla::NewRunnableMethod<CaptureEngine, unsigned int>(
|
|
|
|
- "camera::PCamerasChild::SendGetCaptureDevice",
|
|
|
|
- this,
|
|
|
|
- &CamerasChild::SendGetCaptureDevice,
|
|
|
|
- aCapEngine,
|
|
|
|
- list_number);
|
|
|
|
- LockAndDispatch<> dispatcher(this, __func__, runnable, -1, mZero);
|
|
|
|
- if (dispatcher.Success()) {
|
|
|
|
- base::strlcpy(device_nameUTF8, mReplyDeviceName.get(), device_nameUTF8Length);
|
|
|
|
-@@ -434,19 +436,19 @@ CamerasChild::AllocateCaptureDevice(Capt
|
|
|
|
- const char* unique_idUTF8,
|
|
|
|
- const unsigned int unique_idUTF8Length,
|
|
|
|
- int& aStreamId,
|
|
|
|
- const mozilla::ipc::PrincipalInfo& aPrincipalInfo)
|
|
|
|
- {
|
|
|
|
- LOG((__PRETTY_FUNCTION__));
|
|
|
|
- nsCString unique_id(unique_idUTF8);
|
|
|
|
- nsCOMPtr<nsIRunnable> runnable =
|
|
|
|
-- mozilla::NewNonOwningRunnableMethod<CaptureEngine,
|
|
|
|
-- nsCString,
|
|
|
|
-- const mozilla::ipc::PrincipalInfo&>(
|
|
|
|
-+ mozilla::NewRunnableMethod<CaptureEngine,
|
|
|
|
-+ nsCString,
|
|
|
|
-+ const mozilla::ipc::PrincipalInfo&>(
|
|
|
|
- "camera::PCamerasChild::SendAllocateCaptureDevice",
|
|
|
|
- this,
|
|
|
|
- &CamerasChild::SendAllocateCaptureDevice,
|
|
|
|
- aCapEngine,
|
|
|
|
- unique_id,
|
|
|
|
- aPrincipalInfo);
|
|
|
|
- LockAndDispatch<> dispatcher(this, __func__, runnable, -1, mZero);
|
|
|
|
- if (dispatcher.Success()) {
|
|
|
|
-@@ -470,17 +472,17 @@ CamerasChild::RecvReplyAllocateCaptureDe
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- int
|
|
|
|
- CamerasChild::ReleaseCaptureDevice(CaptureEngine aCapEngine,
|
|
|
|
- const int capture_id)
|
|
|
|
- {
|
|
|
|
- LOG((__PRETTY_FUNCTION__));
|
|
|
|
- nsCOMPtr<nsIRunnable> runnable =
|
|
|
|
-- mozilla::NewNonOwningRunnableMethod<CaptureEngine, int>(
|
|
|
|
-+ mozilla::NewRunnableMethod<CaptureEngine, int>(
|
|
|
|
- "camera::PCamerasChild::SendReleaseCaptureDevice",
|
|
|
|
- this,
|
|
|
|
- &CamerasChild::SendReleaseCaptureDevice,
|
|
|
|
- aCapEngine,
|
|
|
|
- capture_id);
|
|
|
|
- LockAndDispatch<> dispatcher(this, __func__, runnable, -1, mZero);
|
|
|
|
- return dispatcher.ReturnValue();
|
|
|
|
- }
|
|
|
|
-@@ -521,49 +523,52 @@ CamerasChild::StartCapture(CaptureEngine
|
|
|
|
- VideoCaptureCapability capCap(webrtcCaps.width,
|
|
|
|
- webrtcCaps.height,
|
|
|
|
- webrtcCaps.maxFPS,
|
|
|
|
- webrtcCaps.expectedCaptureDelay,
|
|
|
|
- webrtcCaps.rawType,
|
|
|
|
- webrtcCaps.codecType,
|
|
|
|
- webrtcCaps.interlaced);
|
|
|
|
- nsCOMPtr<nsIRunnable> runnable = mozilla::
|
|
|
|
-- NewNonOwningRunnableMethod<CaptureEngine, int, VideoCaptureCapability>(
|
|
|
|
-+ NewRunnableMethod<CaptureEngine, int, VideoCaptureCapability>(
|
|
|
|
- "camera::PCamerasChild::SendStartCapture",
|
|
|
|
- this,
|
|
|
|
- &CamerasChild::SendStartCapture,
|
|
|
|
- aCapEngine,
|
|
|
|
- capture_id,
|
|
|
|
- capCap);
|
|
|
|
- LockAndDispatch<> dispatcher(this, __func__, runnable, -1, mZero);
|
|
|
|
- return dispatcher.ReturnValue();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- int
|
|
|
|
- CamerasChild::StopCapture(CaptureEngine aCapEngine, const int capture_id)
|
|
|
|
- {
|
|
|
|
- LOG((__PRETTY_FUNCTION__));
|
|
|
|
- nsCOMPtr<nsIRunnable> runnable =
|
|
|
|
-- mozilla::NewNonOwningRunnableMethod<CaptureEngine, int>(
|
|
|
|
-+ mozilla::NewRunnableMethod<CaptureEngine, int>(
|
|
|
|
- "camera::PCamerasChild::SendStopCapture",
|
|
|
|
- this,
|
|
|
|
- &CamerasChild::SendStopCapture,
|
|
|
|
- aCapEngine,
|
|
|
|
- capture_id);
|
|
|
|
- LockAndDispatch<> dispatcher(this, __func__, runnable, -1, mZero);
|
|
|
|
- if (dispatcher.Success()) {
|
|
|
|
- RemoveCallback(aCapEngine, capture_id);
|
|
|
|
- }
|
|
|
|
- return dispatcher.ReturnValue();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- void
|
|
|
|
- Shutdown(void)
|
|
|
|
- {
|
|
|
|
- OffTheBooksMutexAutoLock lock(CamerasSingleton::Mutex());
|
|
|
|
-+
|
|
|
|
-+ CamerasSingleton::StartShutdown();
|
|
|
|
-+
|
|
|
|
- CamerasChild* child = CamerasSingleton::Child();
|
|
|
|
- if (!child) {
|
|
|
|
- // We don't want to cause everything to get fired up if we're
|
|
|
|
- // really already shut down.
|
|
|
|
- LOG(("Shutdown when already shut down"));
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- child->ShutdownAll();
|
|
|
|
-@@ -605,17 +610,17 @@ CamerasChild::ShutdownParent()
|
|
|
|
- mIPCIsAlive = false;
|
|
|
|
- monitor.NotifyAll();
|
|
|
|
- }
|
|
|
|
- if (CamerasSingleton::Thread()) {
|
|
|
|
- LOG(("Dispatching actor deletion"));
|
|
|
|
- // Delete the parent actor.
|
|
|
|
- // CamerasChild (this) will remain alive and is only deleted by the
|
|
|
|
- // IPC layer when SendAllDone returns.
|
|
|
|
-- nsCOMPtr<nsIRunnable> deleteRunnable = mozilla::NewNonOwningRunnableMethod(
|
|
|
|
-+ nsCOMPtr<nsIRunnable> deleteRunnable = mozilla::NewRunnableMethod(
|
|
|
|
- "camera::PCamerasChild::SendAllDone", this, &CamerasChild::SendAllDone);
|
|
|
|
- CamerasSingleton::Thread()->Dispatch(deleteRunnable, NS_DISPATCH_NORMAL);
|
|
|
|
- } else {
|
|
|
|
- LOG(("ShutdownParent called without PBackground thread"));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- void
|
|
|
|
-@@ -728,17 +733,17 @@ CamerasChild::CamerasChild()
|
|
|
|
-
|
|
|
|
- MOZ_COUNT_CTOR(CamerasChild);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- CamerasChild::~CamerasChild()
|
|
|
|
- {
|
|
|
|
- LOG(("~CamerasChild: %p", this));
|
|
|
|
-
|
|
|
|
-- {
|
|
|
|
-+ if (!CamerasSingleton::InShutdown()) {
|
|
|
|
- OffTheBooksMutexAutoLock lock(CamerasSingleton::Mutex());
|
|
|
|
- // In normal circumstances we've already shut down and the
|
|
|
|
- // following does nothing. But on fatal IPC errors we will
|
|
|
|
- // get destructed immediately, and should not try to reach
|
|
|
|
- // the parent.
|
|
|
|
- ShutdownChild();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-diff --git a/dom/media/systemservices/CamerasChild.h b/dom/media/systemservices/CamerasChild.h
|
|
|
|
---- a/dom/media/systemservices/CamerasChild.h
|
|
|
|
-+++ b/dom/media/systemservices/CamerasChild.h
|
|
|
|
-@@ -88,16 +88,24 @@ public:
|
|
|
|
- return gTheInstance.get()->mCamerasChildThread;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- static nsCOMPtr<nsIThread>& FakeDeviceChangeEventThread() {
|
|
|
|
- Mutex().AssertCurrentThreadOwns();
|
|
|
|
- return gTheInstance.get()->mFakeDeviceChangeEventThread;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
-+ static bool InShutdown() {
|
|
|
|
-+ return gTheInstance.get()->mInShutdown;
|
|
|
|
-+ }
|
|
|
|
-+
|
|
|
|
-+ static void StartShutdown() {
|
|
|
|
-+ gTheInstance.get()->mInShutdown = true;
|
|
|
|
-+ }
|
|
|
|
-+
|
|
|
|
- private:
|
|
|
|
- static Singleton<CamerasSingleton> gTheInstance;
|
|
|
|
-
|
|
|
|
- // Reinitializing CamerasChild will change the pointers below.
|
|
|
|
- // We don't want this to happen in the middle of preparing IPC.
|
|
|
|
- // We will be alive on destruction, so this needs to be off the books.
|
|
|
|
- mozilla::OffTheBooksMutex mCamerasMutex;
|
|
|
|
-
|
|
|
|
-@@ -105,16 +113,17 @@ private:
|
|
|
|
- // It will set and clear this pointer as appropriate in setup/teardown.
|
|
|
|
- // We'd normally make this a WeakPtr but unfortunately the IPC code already
|
|
|
|
- // uses the WeakPtr mixin in a protected base class of CamerasChild, and in
|
|
|
|
- // any case the object becomes unusable as soon as IPC is tearing down, which
|
|
|
|
- // will be before actual destruction.
|
|
|
|
- CamerasChild* mCameras;
|
|
|
|
- nsCOMPtr<nsIThread> mCamerasChildThread;
|
|
|
|
- nsCOMPtr<nsIThread> mFakeDeviceChangeEventThread;
|
|
|
|
-+ Atomic<bool> mInShutdown;
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- // Get a pointer to a CamerasChild object we can use to do IPC with.
|
|
|
|
- // This does everything needed to set up, including starting the IPC
|
|
|
|
- // channel with PBackground, blocking until thats done, and starting the
|
|
|
|
- // thread to do IPC on. This will fail if we're in shutdown. On success
|
|
|
|
- // it will set up the CamerasSingleton.
|
|
|
|
- CamerasChild* GetCamerasChild();
|
|
|
|
-@@ -144,17 +153,17 @@ class CamerasChild final : public PCamer
|
|
|
|
- ,public DeviceChangeCallback
|
|
|
|
- {
|
|
|
|
- friend class mozilla::ipc::BackgroundChildImpl;
|
|
|
|
- template <class T> friend class mozilla::camera::LockAndDispatch;
|
|
|
|
-
|
|
|
|
- public:
|
|
|
|
- // We are owned by the PBackground thread only. CamerasSingleton
|
|
|
|
- // takes a non-owning reference.
|
|
|
|
-- NS_INLINE_DECL_REFCOUNTING(CamerasChild)
|
|
|
|
-+ NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CamerasChild)
|
|
|
|
-
|
|
|
|
- // IPC messages recevied, received on the PBackground thread
|
|
|
|
- // these are the actual callbacks with data
|
|
|
|
- virtual mozilla::ipc::IPCResult RecvDeliverFrame(const CaptureEngine&, const int&,
|
|
|
|
- mozilla::ipc::Shmem&&,
|
|
|
|
- const VideoFrameProperties & prop) override;
|
|
|
|
- virtual mozilla::ipc::IPCResult RecvFrameSizeChange(const CaptureEngine&, const int&,
|
|
|
|
- const int& w, const int& h) override;
|
|
|