Bug 1678463 - Part 1: Add _WITH_DELETE_ON_EVENT_TARGET macros to nsISupportsImpl, r=mccr8

This also migrates all existing users of _WITH_MAIN_THREAD_DESTRUCTION to the
new macro in nsISupportsImpl.

Differential Revision: https://phabricator.services.mozilla.com/D97825
This commit is contained in:
Nika Layzell 2020-12-14 18:30:51 +00:00
Родитель 93ac2de55b
Коммит 6d17703514
11 изменённых файлов: 144 добавлений и 49 удалений

Просмотреть файл

@ -14,7 +14,6 @@
#include "MediaTrackConstraints.h"
#include "MediaTrackGraphImpl.h"
#include "MediaTrackListener.h"
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
#include "VideoStreamTrack.h"
#include "VideoUtils.h"
#include "mozilla/Base64.h"
@ -303,7 +302,7 @@ class SourceListener : public SupportsWeakPtr {
typedef MozPromise<bool /* aIgnored */, RefPtr<MediaMgrError>, true>
SourceListenerPromise;
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DELETE_ON_MAIN_THREAD(
SourceListener)
SourceListener();
@ -1946,9 +1945,10 @@ RefPtr<MediaManager::MgrPromise> MediaManager::EnumerateRawDevices(
// Need to ask permission to retrieve list of all devices;
// notify frontend observer and wait for callback notification to post task.
const char16_t* const type =
(aVideoInputType != MediaSourceEnum::Camera) ? u"audio"
: (aAudioInputType != MediaSourceEnum::Microphone) ? u"video"
: u"all";
(aVideoInputType != MediaSourceEnum::Camera)
? u"audio"
: (aAudioInputType != MediaSourceEnum::Microphone) ? u"video"
: u"all";
nsCOMPtr<nsIObserverService> obs = services::GetObserverService();
obs->NotifyObservers(static_cast<nsIRunnable*>(task),
"getUserMedia:ask-device-permission", type);

Просмотреть файл

@ -21,7 +21,6 @@
#include "nsHashKeys.h" // for nsUint64HashKey
#include "nsISupportsImpl.h" // for NS_INLINE_DECL_REFCOUNTING
#include "nsIWeakReferenceUtils.h"
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
#include <unordered_map>

Просмотреть файл

@ -8,7 +8,6 @@
#include "nsISupportsImpl.h"
#include "nsIThread.h"
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
class nsISerialEventTarget;
class nsIThread;
@ -17,7 +16,7 @@ namespace mozilla {
namespace layers {
class CompositorThreadHolder final {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DELETE_ON_MAIN_THREAD(
CompositorThreadHolder)
public:

Просмотреть файл

@ -1,29 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef THREADSAFEREFCOUNTINGWITHMAINTHREADDESTRUCTION_H_
#define THREADSAFEREFCOUNTINGWITHMAINTHREADDESTRUCTION_H_
#include "nsISupportsImpl.h"
#include "MainThreadUtils.h"
#include "nsThreadUtils.h"
#define NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION( \
_class) \
private: \
void DeleteOnMainThread() { \
if (NS_IsMainThread()) { \
delete this; \
return; \
} \
NS_DispatchToMainThread(NewNonOwningRunnableMethod( \
#_class "::DeleteOnMainThread", this, &_class::DeleteOnMainThread)); \
} \
\
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DESTROY(_class, \
DeleteOnMainThread())
#endif

Просмотреть файл

@ -32,7 +32,6 @@ EXPORTS += [
"ImageLayers.h",
"ImageTypes.h",
"IMFYCbCrImage.h",
"ipc/ThreadSafeRefcountingWithMainThreadDestruction.h",
"Layers.h",
"LayerScope.h",
"LayerSorter.h",

Просмотреть файл

@ -7,7 +7,7 @@
#ifndef GFX_VR_THREAD_H
#define GFX_VR_THREAD_H
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
#include "nsISupportsImpl.h"
#include "base/thread.h" // for Thread
namespace mozilla {

Просмотреть файл

@ -7,13 +7,13 @@
#ifndef MOZILLA_GFX_VR_VRMANAGERCHILD_H
#define MOZILLA_GFX_VR_VRMANAGERCHILD_H
#include "nsISupportsImpl.h"
#include "mozilla/Attributes.h"
#include "mozilla/dom/WindowBinding.h" // For FrameRequestCallback
#include "mozilla/dom/WebXRBinding.h"
#include "mozilla/dom/XRFrame.h"
#include "mozilla/gfx/PVRManagerChild.h"
#include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
#include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc
#include "mozilla/layers/ISurfaceAllocator.h" // for ISurfaceAllocator
#include "mozilla/layers/LayersTypes.h" // for LayersBackend

Просмотреть файл

@ -13,7 +13,6 @@
#include "base/message_loop.h"
#include "GLTypes.h" // for GLenum
#include "nsISupportsImpl.h"
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
#include "mozilla/gfx/Point.h"
#include "mozilla/MozPromise.h"
#include "mozilla/DataMutex.h"
@ -131,8 +130,7 @@ class RendererEvent {
/// singleton but in some places we pretend it's not). Hopefully we can evolve
/// this in a way that keeps the door open to removing the singleton bits.
class RenderThread final {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(
RenderThread)
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DELETE_ON_MAIN_THREAD(RenderThread)
public:
/// Can be called from any thread.

Просмотреть файл

@ -9,7 +9,6 @@
#include "base/thread.h"
#include "base/message_loop.h"
#include "ThreadSafeRefcountingWithMainThreadDestruction.h"
namespace mozilla {
@ -27,7 +26,7 @@ struct WinCompositorWnds {
};
class WinCompositorWindowThread final {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_MAIN_THREAD_DESTRUCTION(
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DELETE_ON_MAIN_THREAD(
WinCompositorWindowThread)
public:

Просмотреть файл

@ -7,9 +7,10 @@
#include "nsISupportsImpl.h"
#include "mozilla/Assertions.h"
#ifdef MOZ_THREAD_SAFETY_OWNERSHIP_CHECKS_SUPPORTED
#ifndef XPCOM_GLUE_AVOID_NSPR
# include "nsPrintfCString.h"
# include "nsThreadUtils.h"
#endif // MOZ_THREAD_SAFETY_OWNERSHIP_CHECKS_SUPPORTED
#endif
using namespace mozilla;
@ -32,7 +33,8 @@ nsresult NS_FASTCALL NS_TableDrivenQI(void* aThis, REFNSIID aIID,
return NS_ERROR_NO_INTERFACE;
}
#ifdef MOZ_THREAD_SAFETY_OWNERSHIP_CHECKS_SUPPORTED
#ifndef XPCOM_GLUE_AVOID_NSPR
# ifdef MOZ_THREAD_SAFETY_OWNERSHIP_CHECKS_SUPPORTED
nsAutoOwningThread::nsAutoOwningThread() : mThread(PR_GetCurrentThread()) {}
void nsAutoOwningThread::AssertCurrentThreadOwnsMe(const char* msg) const {
@ -67,4 +69,76 @@ bool nsAutoOwningEventTarget::IsCurrentThread() const {
return mTarget->IsOnCurrentThread();
}
# endif
namespace mozilla::detail {
class ProxyDeleteVoidRunnable final : public CancelableRunnable {
public:
ProxyDeleteVoidRunnable(const char* aName, void* aPtr,
DeleteVoidFunction* aDeleteFunc)
: CancelableRunnable(aName), mPtr(aPtr), mDeleteFunc(aDeleteFunc) {}
NS_IMETHOD Run() override {
if (mPtr) {
mDeleteFunc(mPtr);
mPtr = nullptr;
}
return NS_OK;
}
// Mimics the behaviour in `ProxyRelease`, freeing the resource when
// cancelled.
nsresult Cancel() override { return Run(); }
# ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
NS_IMETHOD GetName(nsACString& aName) override {
if (mName) {
aName.Append(mName);
} else {
aName.AssignLiteral("ProxyDeleteVoidRunnable");
}
return NS_OK;
}
# endif
private:
~ProxyDeleteVoidRunnable() {
if (mPtr) {
# ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
NS_WARNING(
nsPrintfCString(
"ProxyDeleteVoidRunnable for '%s' never run, leaking!", mName)
.get());
# else
NS_WARNING("ProxyDeleteVoidRunnable never run, leaking!");
# endif
}
}
void* mPtr;
DeleteVoidFunction* mDeleteFunc;
};
void ProxyDeleteVoid(const char* aName, nsISerialEventTarget* aTarget,
void* aPtr, DeleteVoidFunction* aDeleteFunc) {
MOZ_ASSERT(aName);
MOZ_ASSERT(aPtr);
MOZ_ASSERT(aDeleteFunc);
if (!aTarget) {
NS_WARNING(nsPrintfCString("no target for '%s', leaking!", aName).get());
return;
}
if (aTarget->IsOnCurrentThread()) {
aDeleteFunc(aPtr);
return;
}
nsresult rv = aTarget->Dispatch(
MakeAndAddRef<ProxyDeleteVoidRunnable>(aName, aPtr, aDeleteFunc),
NS_DISPATCH_NORMAL);
if (NS_FAILED(rv)) {
NS_WARNING(nsPrintfCString("failed to post '%s', leaking!", aName).get());
}
}
} // namespace mozilla::detail
#endif

Просмотреть файл

@ -735,6 +735,62 @@ class ThreadSafeAutoRefCnt {
NS_INLINE_DECL_THREADSAFE_VIRTUAL_REFCOUNTING_WITH_DESTROY( \
_class, delete (this), __VA_ARGS__)
#if !defined(XPCOM_GLUE_AVOID_NSPR)
class nsISerialEventTarget;
namespace mozilla {
// Forward-declare `GetMainThreadSerialEventTarget`, as `nsISupportsImpl.h`
// cannot include `nsThreadUtils.h`.
nsISerialEventTarget* GetMainThreadSerialEventTarget();
namespace detail {
using DeleteVoidFunction = void(void*);
void ProxyDeleteVoid(const char* aRunnableName,
nsISerialEventTarget* aEventTarget, void* aSelf,
DeleteVoidFunction* aDeleteFunc);
} // namespace detail
} // namespace mozilla
/**
* Helper for _WITH_DELETE_ON_EVENT_TARGET threadsafe refcounting macros which
* provides an implementation of `_destroy`
*/
# define NS_PROXY_DELETE_TO_EVENT_TARGET(_class, _target) \
::mozilla::detail::ProxyDeleteVoid( \
"ProxyDelete " #_class, _target, this, \
[](void* self) { delete static_cast<_class*>(self); })
/**
* Use this macro to declare and implement the AddRef & Release methods for a
* given non-XPCOM <i>_class</i> in a threadsafe manner, ensuring the
* destructor runs on a specific nsISerialEventTarget.
*
* DOES NOT DO REFCOUNT STABILIZATION!
*
* @param _class The name of the class implementing the method
* @param _target nsISerialEventTarget to run the class's destructor on
* @param optional override Mark the AddRef & Release methods as overrides
*/
# define NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DELETE_ON_EVENT_TARGET( \
_class, _target, ...) \
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DESTROY( \
_class, NS_PROXY_DELETE_TO_EVENT_TARGET(_class, _target), __VA_ARGS__)
/**
* Use this macro to declare and implement the AddRef & Release methods for a
* given non-XPCOM <i>_class</i> in a threadsafe manner, ensuring the
* destructor runs on the main thread.
*
* DOES NOT DO REFCOUNT STABILIZATION!
*
* @param _class The name of the class implementing the method
* @param optional override Mark the AddRef & Release methods as overrides
*/
# define NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DELETE_ON_MAIN_THREAD( \
_class, ...) \
NS_INLINE_DECL_THREADSAFE_REFCOUNTING_WITH_DELETE_ON_EVENT_TARGET( \
_class, ::mozilla::GetMainThreadSerialEventTarget(), __VA_ARGS__)
#endif
/**
* Use this macro in interface classes that you want to be able to reference
* using RefPtr, but don't want to provide a refcounting implemenation. The