Bug 1543282 part 1: Reference counting for DocAccessibleParent. r=eeejay,nika

Supporting out-of-process iframes requires us to hold onto a DocAccessibleParent in BrowserBridgeParent.
However, we can't guarantee the order of cleanup between the two content processes.
Therefore, we need reference counting to kee the object alive.

Differential Revision: https://phabricator.services.mozilla.com/D32277

--HG--
extra : moz-landing-system : lando
This commit is contained in:
James Teh 2019-05-28 17:42:59 +00:00
Родитель 66cb95a768
Коммит 41261b6bd4
3 изменённых файлов: 23 добавлений и 15 удалений

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

@ -676,12 +676,17 @@ void DocAccessibleParent::MaybeInitWindowEmulation() {
isActive = browserParent->GetDocShellIsActive();
}
nsWinUtils::NativeWindowCreateProc onCreate([this](HWND aHwnd) -> void {
// onCreate is guaranteed to be called synchronously by
// nsWinUtils::CreateNativeWindow, so this reference isn't really necessary.
// However, static analysis complains without it.
RefPtr<DocAccessibleParent> thisRef = this;
nsWinUtils::NativeWindowCreateProc onCreate([thisRef](HWND aHwnd) -> void {
IDispatchHolder hWndAccHolder;
::SetPropW(aHwnd, kPropNameDocAccParent, reinterpret_cast<HANDLE>(this));
::SetPropW(aHwnd, kPropNameDocAccParent,
reinterpret_cast<HANDLE>(thisRef.get()));
SetEmulatedWindowHandle(aHwnd);
thisRef->SetEmulatedWindowHandle(aHwnd);
RefPtr<IAccessible> hwndAcc;
if (SUCCEEDED(::AccessibleObjectFromWindow(
@ -692,8 +697,9 @@ void DocAccessibleParent::MaybeInitWindowEmulation() {
mscom::ToProxyUniquePtr(std::move(wrapped))));
}
Unused << SendEmulatedWindow(
reinterpret_cast<uintptr_t>(mEmulatedWindowHandle), hWndAccHolder);
Unused << thisRef->SendEmulatedWindow(
reinterpret_cast<uintptr_t>(thisRef->mEmulatedWindowHandle),
hWndAccHolder);
});
HWND parentWnd = reinterpret_cast<HWND>(rootDocument->GetNativeWindow());

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

@ -26,6 +26,8 @@ class xpcAccessibleGeneric;
class DocAccessibleParent : public ProxyAccessible,
public PDocAccessibleParent {
public:
NS_INLINE_DECL_REFCOUNTING(DocAccessibleParent);
DocAccessibleParent()
: ProxyAccessible(this),
mParentDoc(kNoParentDoc),
@ -34,20 +36,12 @@ class DocAccessibleParent : public ProxyAccessible,
#endif // defined(XP_WIN)
mTopLevel(false),
mShutdown(false) {
MOZ_COUNT_CTOR_INHERITED(DocAccessibleParent, ProxyAccessible);
sMaxDocID++;
mActorID = sMaxDocID;
MOZ_ASSERT(!LiveDocs().Get(mActorID));
LiveDocs().Put(mActorID, this);
}
~DocAccessibleParent() {
LiveDocs().Remove(mActorID);
MOZ_COUNT_DTOR_INHERITED(DocAccessibleParent, ProxyAccessible);
MOZ_ASSERT(mChildDocs.Length() == 0);
MOZ_ASSERT(!ParentDoc());
}
void SetTopLevel() { mTopLevel = true; }
bool IsTopLevel() const { return mTopLevel; }
@ -221,6 +215,12 @@ class DocAccessibleParent : public ProxyAccessible,
#endif
private:
~DocAccessibleParent() {
LiveDocs().Remove(mActorID);
MOZ_ASSERT(mChildDocs.Length() == 0);
MOZ_ASSERT(!ParentDoc());
}
class ProxyEntry : public PLDHashEntryHdr {
public:
explicit ProxyEntry(const void*) : mProxy(nullptr) {}

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

@ -1059,7 +1059,8 @@ a11y::PDocAccessibleParent* BrowserParent::AllocPDocAccessibleParent(
PDocAccessibleParent* aParent, const uint64_t&, const uint32_t&,
const IAccessibleHolder&) {
#ifdef ACCESSIBILITY
return new a11y::DocAccessibleParent();
// Reference freed in DeallocPDocAccessibleParent.
return do_AddRef(new a11y::DocAccessibleParent()).take();
#else
return nullptr;
#endif
@ -1067,7 +1068,8 @@ a11y::PDocAccessibleParent* BrowserParent::AllocPDocAccessibleParent(
bool BrowserParent::DeallocPDocAccessibleParent(PDocAccessibleParent* aParent) {
#ifdef ACCESSIBILITY
delete static_cast<a11y::DocAccessibleParent*>(aParent);
// Free reference from AllocPDocAccessibleParent.
static_cast<a11y::DocAccessibleParent*>(aParent)->Release();
#endif
return true;
}