Backed out changeset e79129082f4a (bug 1297474) for crashes in m-oth windows tests

This commit is contained in:
Carsten "Tomcat" Book 2016-11-21 10:33:49 +01:00
parent 16f0e1705b
commit a6b76e9898
18 changed files with 51 additions and 662 deletions

View File

@ -85,20 +85,6 @@ DocManager::FindAccessibleInCache(nsINode* aNode) const
return nullptr; return nullptr;
} }
void
DocManager::RemoveFromXPCDocumentCache(DocAccessible* aDocument)
{
xpcAccessibleDocument* xpcDoc = mXPCDocumentCache.GetWeak(aDocument);
if (xpcDoc) {
xpcDoc->Shutdown();
mXPCDocumentCache.Remove(aDocument);
}
if (!HasXPCDocuments()) {
MaybeShutdownAccService(nsAccessibilityService::eXPCOM);
}
}
void void
DocManager::NotifyOfDocumentShutdown(DocAccessible* aDocument, DocManager::NotifyOfDocumentShutdown(DocAccessible* aDocument,
nsIDocument* aDOMDocument) nsIDocument* aDOMDocument)
@ -113,28 +99,23 @@ DocManager::NotifyOfDocumentShutdown(DocAccessible* aDocument,
return; return;
} }
RemoveFromXPCDocumentCache(aDocument); xpcAccessibleDocument* xpcDoc = mXPCDocumentCache.GetWeak(aDocument);
if (xpcDoc) {
xpcDoc->Shutdown();
mXPCDocumentCache.Remove(aDocument);
}
mDocAccessibleCache.Remove(aDOMDocument); mDocAccessibleCache.Remove(aDOMDocument);
} }
void void
DocManager::RemoveFromRemoteXPCDocumentCache(DocAccessibleParent* aDoc) DocManager::NotifyOfRemoteDocShutdown(DocAccessibleParent* aDoc)
{ {
xpcAccessibleDocument* doc = GetCachedXPCDocument(aDoc); xpcAccessibleDocument* doc = GetCachedXPCDocument(aDoc);
if (doc) { if (doc) {
doc->Shutdown(); doc->Shutdown();
sRemoteXPCDocumentCache->Remove(aDoc); sRemoteXPCDocumentCache->Remove(aDoc);
} }
if (sRemoteXPCDocumentCache && sRemoteXPCDocumentCache->Count() == 0) {
MaybeShutdownAccService(nsAccessibilityService::eXPCOM);
}
}
void
DocManager::NotifyOfRemoteDocShutdown(DocAccessibleParent* aDoc)
{
RemoveFromRemoteXPCDocumentCache(aDoc);
} }
xpcAccessibleDocument* xpcAccessibleDocument*

View File

@ -66,8 +66,6 @@ public:
void NotifyOfDocumentShutdown(DocAccessible* aDocument, void NotifyOfDocumentShutdown(DocAccessible* aDocument,
nsIDocument* aDOMDocument); nsIDocument* aDOMDocument);
void RemoveFromXPCDocumentCache(DocAccessible* aDocument);
/** /**
* Return XPCOM accessible document. * Return XPCOM accessible document.
*/ */
@ -97,8 +95,6 @@ public:
*/ */
static void NotifyOfRemoteDocShutdown(DocAccessibleParent* adoc); static void NotifyOfRemoteDocShutdown(DocAccessibleParent* adoc);
static void RemoveFromRemoteXPCDocumentCache(DocAccessibleParent* aDoc);
/** /**
* Get a XPC document for a remote document. * Get a XPC document for a remote document.
*/ */
@ -127,12 +123,6 @@ protected:
*/ */
void Shutdown(); void Shutdown();
bool HasXPCDocuments()
{
return mXPCDocumentCache.Count() > 0 ||
(sRemoteXPCDocumentCache && sRemoteXPCDocumentCache->Count() > 0);
}
private: private:
DocManager(const DocManager&); DocManager(const DocManager&);
DocManager& operator =(const DocManager&); DocManager& operator =(const DocManager&);

View File

@ -1815,8 +1815,7 @@ MaybeShutdownAccService(uint32_t aFormerConsumer)
} }
if (nsCoreUtils::AccEventObserversExist() || if (nsCoreUtils::AccEventObserversExist() ||
xpcAccessibilityService::IsInUse() || xpcAccessibilityService::IsInUse()) {
accService->HasXPCDocuments()) {
// Still used by XPCOM // Still used by XPCOM
nsAccessibilityService::gConsumers = nsAccessibilityService::gConsumers =
(nsAccessibilityService::gConsumers & ~aFormerConsumer) | (nsAccessibilityService::gConsumers & ~aFormerConsumer) |

View File

@ -4,21 +4,9 @@ support-files =
head.js head.js
shared-head.js shared-head.js
[browser_shutdown_acc_reference.js]
[browser_shutdown_doc_acc_reference.js]
[browser_shutdown_multi_acc_reference_obj.js]
[browser_shutdown_multi_acc_reference_doc.js]
[browser_shutdown_multi_reference.js] [browser_shutdown_multi_reference.js]
[browser_shutdown_parent_own_reference.js] [browser_shutdown_parent_own_reference.js]
skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content. skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content.
[browser_shutdown_proxy_acc_reference.js]
skip-if = !e10s || (os == 'win') # e10s specific test for a11y start/shutdown between parent and content.
[browser_shutdown_proxy_doc_acc_reference.js]
skip-if = !e10s || (os == 'win') # e10s specific test for a11y start/shutdown between parent and content.
[browser_shutdown_multi_proxy_acc_reference_doc.js]
skip-if = !e10s || (os == 'win') # e10s specific test for a11y start/shutdown between parent and content.
[browser_shutdown_multi_proxy_acc_reference_obj.js]
skip-if = !e10s || (os == 'win') # e10s specific test for a11y start/shutdown between parent and content.
[browser_shutdown_remote_no_reference.js] [browser_shutdown_remote_no_reference.js]
skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content. skip-if = !e10s # e10s specific test for a11y start/shutdown between parent and content.
[browser_shutdown_remote_only.js] [browser_shutdown_remote_only.js]

View File

@ -1,55 +0,0 @@
/* 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/. */
'use strict';
add_task(function* () {
// Create a11y service.
let a11yInit = initPromise();
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
yield a11yInit;
ok(accService, 'Service initialized');
// Accessible object reference will live longer than the scope of this
// function.
let acc = yield new Promise(resolve => {
let intervalId = setInterval(() => {
let tabAcc = accService.getAccessibleFor(gBrowser.mCurrentTab);
if (tabAcc) {
clearInterval(intervalId);
resolve(tabAcc);
}
}, 10);
});
ok(acc, 'Accessible object is created');
let canShutdown = false;
// This promise will resolve only if canShutdown flag is set to true. If
// 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
// down, the promise will reject.
let a11yShutdown = new Promise((resolve, reject) =>
shutdownPromise().then(flag => canShutdown ? resolve() :
reject('Accessible service was shut down incorrectly')));
accService = null;
ok(!accService, 'Service is removed');
// Force garbage collection that should not trigger shutdown because there is
// a reference to an accessible object.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
// Now allow a11y service to shutdown.
canShutdown = true;
// Remove a reference to an accessible object.
acc = null;
ok(!acc, 'Accessible object is removed');
// Force garbage collection that should now trigger shutdown.
forceGC();
yield a11yShutdown;
});

View File

@ -1,47 +0,0 @@
/* 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/. */
'use strict';
add_task(function* () {
// Create a11y service.
let a11yInit = initPromise();
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
yield a11yInit;
ok(accService, 'Service initialized');
// Accessible document reference will live longer than the scope of this
// function.
let docAcc = accService.getAccessibleFor(document);
ok(docAcc, 'Accessible document is created');
let canShutdown = false;
// This promise will resolve only if canShutdown flag is set to true. If
// 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
// down, the promise will reject.
let a11yShutdown = new Promise((resolve, reject) =>
shutdownPromise().then(flag => canShutdown ? resolve() :
reject('Accessible service was shut down incorrectly')));
accService = null;
ok(!accService, 'Service is removed');
// Force garbage collection that should not trigger shutdown because there is
// a reference to an accessible document.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
// Now allow a11y service to shutdown.
canShutdown = true;
// Remove a reference to an accessible document.
docAcc = null;
ok(!docAcc, 'Accessible document is removed');
// Force garbage collection that should now trigger shutdown.
forceGC();
yield a11yShutdown;
});

View File

@ -1,67 +0,0 @@
/* 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/. */
'use strict';
add_task(function* () {
// Create a11y service.
let a11yInit = initPromise();
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
yield a11yInit;
ok(accService, 'Service initialized');
let docAcc = accService.getAccessibleFor(document);
ok(docAcc, 'Accessible document is created');
// Accessible object reference will live longer than the scope of this
// function.
let acc = yield new Promise(resolve => {
let intervalId = setInterval(() => {
let tabAcc = accService.getAccessibleFor(gBrowser.mCurrentTab);
if (tabAcc) {
clearInterval(intervalId);
resolve(tabAcc);
}
}, 10);
});
ok(acc, 'Accessible object is created');
let canShutdown = false;
// This promise will resolve only if canShutdown flag is set to true. If
// 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
// down, the promise will reject.
let a11yShutdown = new Promise((resolve, reject) =>
shutdownPromise().then(flag => canShutdown ? resolve() :
reject('Accessible service was shut down incorrectly')));
accService = null;
ok(!accService, 'Service is removed');
// Force garbage collection that should not trigger shutdown because there are
// references to accessible objects.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
// Remove a reference to an accessible object.
acc = null;
ok(!acc, 'Accessible object is removed');
// Force garbage collection that should not trigger shutdown because there is
// a reference to an accessible document.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
// Now allow a11y service to shutdown.
canShutdown = true;
// Remove a reference to an accessible document.
docAcc = null;
ok(!docAcc, 'Accessible document is removed');
// Force garbage collection that should now trigger shutdown.
forceGC();
yield a11yShutdown;
});

View File

@ -1,67 +0,0 @@
/* 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/. */
'use strict';
add_task(function* () {
// Create a11y service.
let a11yInit = initPromise();
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
yield a11yInit;
ok(accService, 'Service initialized');
let docAcc = accService.getAccessibleFor(document);
ok(docAcc, 'Accessible document is created');
// Accessible object reference will live longer than the scope of this
// function.
let acc = yield new Promise(resolve => {
let intervalId = setInterval(() => {
let tabAcc = accService.getAccessibleFor(gBrowser.mCurrentTab);
if (tabAcc) {
clearInterval(intervalId);
resolve(tabAcc);
}
}, 10);
});
ok(acc, 'Accessible object is created');
let canShutdown = false;
// This promise will resolve only if canShutdown flag is set to true. If
// 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
// down, the promise will reject.
let a11yShutdown = new Promise((resolve, reject) =>
shutdownPromise().then(flag => canShutdown ? resolve() :
reject('Accessible service was shut down incorrectly')));
accService = null;
ok(!accService, 'Service is removed');
// Force garbage collection that should not trigger shutdown because there are
// references to accessible objects.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
// Remove a reference to an accessible document.
docAcc = null;
ok(!docAcc, 'Accessible document is removed');
// Force garbage collection that should not trigger shutdown because there is
// a reference to an accessible object.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
// Now allow a11y service to shutdown.
canShutdown = true;
// Remove a reference to an accessible object.
acc = null;
ok(!acc, 'Accessible object is removed');
// Force garbage collection that should now trigger shutdown.
forceGC();
yield a11yShutdown;
});

View File

@ -1,76 +0,0 @@
/* 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/. */
'use strict';
add_task(function* () {
// Making sure that the e10s is enabled on Windows for testing.
yield setE10sPrefs();
let docLoaded = waitForEvent(
Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE, 'body');
let a11yInit = initPromise();
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
ok(accService, 'Service initialized');
yield a11yInit;
yield BrowserTestUtils.withNewTab({
gBrowser,
url: `data:text/html,
<html>
<head>
<meta charset="utf-8"/>
<title>Accessibility Test</title>
</head>
<body id="body"><div id="div"></div></body>
</html>`
}, function*(browser) {
let docLoadedEvent = yield docLoaded;
let docAcc = docLoadedEvent.accessibleDocument;
ok(docAcc, 'Accessible document proxy is created');
// Remove unnecessary dangling references
docLoaded = null;
docLoadedEvent = null;
forceGC();
let acc = docAcc.getChildAt(0);
ok(acc, 'Accessible proxy is created');
let canShutdown = false;
let a11yShutdown = new Promise((resolve, reject) =>
shutdownPromise().then(flag => canShutdown ? resolve() :
reject('Accessible service was shut down incorrectly')));
accService = null;
ok(!accService, 'Service is removed');
// Force garbage collection that should not trigger shutdown because there
// is a reference to an accessible proxy.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
// Remove a reference to an accessible proxy.
acc = null;
ok(!acc, 'Accessible proxy is removed');
// Force garbage collection that should not trigger shutdown because there is
// a reference to an accessible document proxy.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
// Now allow a11y service to shutdown.
canShutdown = true;
// Remove a last reference to an accessible document proxy.
docAcc = null;
ok(!docAcc, 'Accessible document proxy is removed');
// Force garbage collection that should now trigger shutdown.
forceGC();
yield a11yShutdown;
});
// Unsetting e10s related preferences.
yield unsetE10sPrefs();
});

View File

@ -1,76 +0,0 @@
/* 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/. */
'use strict';
add_task(function* () {
// Making sure that the e10s is enabled on Windows for testing.
yield setE10sPrefs();
let docLoaded = waitForEvent(
Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE, 'body');
let a11yInit = initPromise();
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
ok(accService, 'Service initialized');
yield a11yInit;
yield BrowserTestUtils.withNewTab({
gBrowser,
url: `data:text/html,
<html>
<head>
<meta charset="utf-8"/>
<title>Accessibility Test</title>
</head>
<body id="body"><div id="div"></div></body>
</html>`
}, function*(browser) {
let docLoadedEvent = yield docLoaded;
let docAcc = docLoadedEvent.accessibleDocument;
ok(docAcc, 'Accessible document proxy is created');
// Remove unnecessary dangling references
docLoaded = null;
docLoadedEvent = null;
forceGC();
let acc = docAcc.getChildAt(0);
ok(acc, 'Accessible proxy is created');
let canShutdown = false;
let a11yShutdown = new Promise((resolve, reject) =>
shutdownPromise().then(flag => canShutdown ? resolve() :
reject('Accessible service was shut down incorrectly')));
accService = null;
ok(!accService, 'Service is removed');
// Force garbage collection that should not trigger shutdown because there
// is a reference to an accessible proxy.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
// Remove a reference to an accessible document proxy.
docAcc = null;
ok(!docAcc, 'Accessible document proxy is removed');
// Force garbage collection that should not trigger shutdown because there is
// a reference to an accessible proxy.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
// Now allow a11y service to shutdown.
canShutdown = true;
// Remove a last reference to an accessible proxy.
acc = null;
ok(!acc, 'Accessible proxy is removed');
// Force garbage collection that should now trigger shutdown.
forceGC();
yield a11yShutdown;
});
// Unsetting e10s related preferences.
yield unsetE10sPrefs();
});

View File

@ -21,7 +21,7 @@ add_task(function* () {
info('Removing all service references'); info('Removing all service references');
let canShutdown = false; let canShutdown = false;
// This promise will resolve only if canShutdown flag is set to true. If // This promise will resolve only if canShutdonw flag is set to true. If
// 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut // 'a11y-init-or-shutdown' event with '0' flag comes before it can be shut
// down, the promise will reject. // down, the promise will reject.
let a11yShutdown = new Promise((resolve, reject) => let a11yShutdown = new Promise((resolve, reject) =>

View File

@ -1,64 +0,0 @@
/* 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/. */
'use strict';
add_task(function* () {
// Making sure that the e10s is enabled on Windows for testing.
yield setE10sPrefs();
let a11yInit = initPromise();
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
ok(accService, 'Service initialized');
yield a11yInit;
yield BrowserTestUtils.withNewTab({
gBrowser,
url: `data:text/html,
<html>
<head>
<meta charset="utf-8"/>
<title>Accessibility Test</title>
</head>
<body><div id="div" style="visibility: hidden;"></div></body>
</html>`
}, function*(browser) {
let onShow = waitForEvent(Ci.nsIAccessibleEvent.EVENT_SHOW, 'div');
yield invokeSetStyle(browser, 'div', 'visibility', 'visible');
let showEvent = yield onShow;
let divAcc = showEvent.accessible;
ok(divAcc, 'Accessible proxy is created');
// Remove unnecessary dangling references
onShow = null;
showEvent = null;
forceGC();
let canShutdown = false;
let a11yShutdown = new Promise((resolve, reject) =>
shutdownPromise().then(flag => canShutdown ? resolve() :
reject('Accessible service was shut down incorrectly')));
accService = null;
ok(!accService, 'Service is removed');
// Force garbage collection that should not trigger shutdown because there
// is a reference to an accessible proxy.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
// Now allow a11y service to shutdown.
canShutdown = true;
// Remove a last reference to an accessible proxy.
divAcc = null;
ok(!divAcc, 'Accessible proxy is removed');
// Force garbage collection that should now trigger shutdown.
forceGC();
yield a11yShutdown;
});
// Unsetting e10s related preferences.
yield unsetE10sPrefs();
});

View File

@ -1,64 +0,0 @@
/* 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/. */
'use strict';
add_task(function* () {
// Making sure that the e10s is enabled on Windows for testing.
yield setE10sPrefs();
let docLoaded = waitForEvent(
Ci.nsIAccessibleEvent.EVENT_DOCUMENT_LOAD_COMPLETE, 'body');
let a11yInit = initPromise();
let accService = Cc['@mozilla.org/accessibilityService;1'].getService(
Ci.nsIAccessibilityService);
ok(accService, 'Service initialized');
yield a11yInit;
yield BrowserTestUtils.withNewTab({
gBrowser,
url: `data:text/html,
<html>
<head>
<meta charset="utf-8"/>
<title>Accessibility Test</title>
</head>
<body id="body"></body>
</html>`
}, function*(browser) {
let docLoadedEvent = yield docLoaded;
let docAcc = docLoadedEvent.accessibleDocument;
ok(docAcc, 'Accessible document proxy is created');
// Remove unnecessary dangling references
docLoaded = null;
docLoadedEvent = null;
forceGC();
let canShutdown = false;
let a11yShutdown = new Promise((resolve, reject) =>
shutdownPromise().then(flag => canShutdown ? resolve() :
reject('Accessible service was shut down incorrectly')));
accService = null;
ok(!accService, 'Service is removed');
// Force garbage collection that should not trigger shutdown because there
// is a reference to an accessible proxy.
forceGC();
// Have some breathing room when removing a11y service references.
yield new Promise(resolve => executeSoon(resolve));
// Now allow a11y service to shutdown.
canShutdown = true;
// Remove a last reference to an accessible document proxy.
docAcc = null;
ok(!docAcc, 'Accessible document proxy is removed');
// Force garbage collection that should now trigger shutdown.
forceGC();
yield a11yShutdown;
});
// Unsetting e10s related preferences.
yield unsetE10sPrefs();
});

View File

@ -4,8 +4,8 @@
'use strict'; 'use strict';
/* exported initPromise, shutdownPromise, waitForEvent, setE10sPrefs, /* exported initPromise, shutdownPromise,
unsetE10sPrefs, forceGC */ setE10sPrefs, unsetE10sPrefs, forceGC */
/** /**
* Set e10s related preferences in the test environment. * Set e10s related preferences in the test environment.
@ -107,34 +107,10 @@ function shutdownPromise(contentBrowser) {
() => ok(false, 'Service initialized incorrectly')); () => ok(false, 'Service initialized incorrectly'));
} }
/**
* Simpler verions of waitForEvent defined in
* accessible/tests/browser/e10s/events.js
*/
function waitForEvent(eventType, expectedId) {
return new Promise(resolve => {
let eventObserver = {
observe(subject) {
let event = subject.QueryInterface(Ci.nsIAccessibleEvent);
if (event.eventType === eventType &&
event.accessible.id === expectedId) {
Services.obs.removeObserver(this, 'accessible-event');
resolve(event);
}
}
};
Services.obs.addObserver(eventObserver, 'accessible-event', false);
});
}
/** /**
* Force garbage collection. * Force garbage collection.
*/ */
function forceGC() { function forceGC() {
SpecialPowers.gc(); Cu.forceCC();
SpecialPowers.forceGC(); Cu.forceGC();
SpecialPowers.forceCC();
SpecialPowers.gc();
SpecialPowers.forceGC();
SpecialPowers.forceCC();
} }

View File

@ -17,28 +17,26 @@ using namespace mozilla;
using namespace mozilla::a11y; using namespace mozilla::a11y;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsISupports // nsISupports and cycle collection
NS_IMPL_CYCLE_COLLECTION_CLASS(xpcAccessibleDocument)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(xpcAccessibleDocument,
xpcAccessibleGeneric)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCache)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(xpcAccessibleDocument,
xpcAccessibleGeneric)
tmp->mCache.Clear();
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(xpcAccessibleDocument)
NS_INTERFACE_MAP_ENTRY(nsIAccessibleDocument)
NS_INTERFACE_MAP_END_INHERITING(xpcAccessibleHyperText)
NS_IMPL_QUERY_INTERFACE_INHERITED(xpcAccessibleDocument, xpcAccessibleHyperText,
nsIAccessibleDocument)
NS_IMPL_ADDREF_INHERITED(xpcAccessibleDocument, xpcAccessibleHyperText) NS_IMPL_ADDREF_INHERITED(xpcAccessibleDocument, xpcAccessibleHyperText)
NS_IMETHODIMP_(MozExternalRefCountType) xpcAccessibleDocument::Release(void) NS_IMPL_RELEASE_INHERITED(xpcAccessibleDocument, xpcAccessibleHyperText)
{
nsrefcnt r = xpcAccessibleHyperText::Release();
NS_LOG_RELEASE(this, r, "xpcAccessibleDocument");
// The only reference to the xpcAccessibleDocument is in DocManager's cache.
if (r == 1 && !mIntl.IsNull() && mCache.Count() == 0) {
if (mIntl.IsAccessible()) {
GetAccService()->RemoveFromXPCDocumentCache(
mIntl.AsAccessible()->AsDoc());
} else {
GetAccService()->RemoveFromRemoteXPCDocumentCache(
mIntl.AsProxy()->AsDoc());
}
}
return r;
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsIAccessibleDocument // nsIAccessibleDocument
@ -181,7 +179,7 @@ xpcAccessibleDocument::GetAccessible(Accessible* aAccessible)
if (aAccessible->IsDoc()) if (aAccessible->IsDoc())
return this; return this;
xpcAccessibleGeneric* xpcAcc = mCache.Get(aAccessible); xpcAccessibleGeneric* xpcAcc = mCache.GetWeak(aAccessible);
if (xpcAcc) if (xpcAcc)
return xpcAcc; return xpcAcc;
@ -209,7 +207,7 @@ xpcAccessibleDocument::GetXPCAccessible(ProxyAccessible* aProxy)
return this; return this;
} }
xpcAccessibleGeneric* acc = mCache.Get(aProxy); xpcAccessibleGeneric* acc = mCache.GetWeak(aProxy);
if (acc) { if (acc) {
return acc; return acc;
} }
@ -219,7 +217,7 @@ xpcAccessibleDocument::GetXPCAccessible(ProxyAccessible* aProxy)
if (aProxy->mHasValue) { if (aProxy->mHasValue) {
interfaces |= eValue; interfaces |= eValue;
} }
if (aProxy->mIsHyperLink) { if (aProxy->mIsHyperLink) {
interfaces |= eHyperLink; interfaces |= eHyperLink;
} }

View File

@ -32,6 +32,8 @@ public:
mRemote(true) {} mRemote(true) {}
NS_DECL_ISUPPORTS_INHERITED NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(xpcAccessibleDocument,
xpcAccessibleGeneric)
// nsIAccessibleDocument // nsIAccessibleDocument
NS_IMETHOD GetURL(nsAString& aURL) final override; NS_IMETHOD GetURL(nsAString& aURL) final override;
@ -73,43 +75,33 @@ private:
void NotifyOfShutdown(Accessible* aAccessible) void NotifyOfShutdown(Accessible* aAccessible)
{ {
MOZ_ASSERT(!mRemote); MOZ_ASSERT(!mRemote);
xpcAccessibleGeneric* xpcAcc = mCache.Get(aAccessible); xpcAccessibleGeneric* xpcAcc = mCache.GetWeak(aAccessible);
if (xpcAcc) { if (xpcAcc)
xpcAcc->Shutdown(); xpcAcc->Shutdown();
}
mCache.Remove(aAccessible); mCache.Remove(aAccessible);
if (mCache.Count() == 0 && mRefCnt == 1) {
GetAccService()->RemoveFromXPCDocumentCache(
mIntl.AsAccessible()->AsDoc());
}
} }
void NotifyOfShutdown(ProxyAccessible* aProxy) void NotifyOfShutdown(ProxyAccessible* aProxy)
{ {
MOZ_ASSERT(mRemote); MOZ_ASSERT(mRemote);
xpcAccessibleGeneric* xpcAcc = mCache.Get(aProxy); xpcAccessibleGeneric* acc = mCache.GetWeak(aProxy);
if (xpcAcc) { if (acc) {
xpcAcc->Shutdown(); acc->Shutdown();
} }
mCache.Remove(aProxy); mCache.Remove(aProxy);
if (mCache.Count() == 0 && mRefCnt == 1) {
GetAccService()->RemoveFromRemoteXPCDocumentCache(
mIntl.AsProxy()->AsDoc());
}
} }
friend class DocManager; friend class DocManager;
friend class DocAccessible; friend class DocAccessible;
friend class ProxyAccessible; friend class ProxyAccessible;
friend class ProxyAccessibleBase<ProxyAccessible>; friend class ProxyAccessibleBase<ProxyAccessible>;
friend class xpcAccessibleGeneric;
xpcAccessibleDocument(const xpcAccessibleDocument&) = delete; xpcAccessibleDocument(const xpcAccessibleDocument&) = delete;
xpcAccessibleDocument& operator =(const xpcAccessibleDocument&) = delete; xpcAccessibleDocument& operator =(const xpcAccessibleDocument&) = delete;
nsDataHashtable<nsPtrHashKey<const void>, xpcAccessibleGeneric*> mCache; nsRefPtrHashtable<nsPtrHashKey<const void>, xpcAccessibleGeneric> mCache;
bool mRemote; bool mRemote;
}; };

View File

@ -9,9 +9,11 @@
using namespace mozilla::a11y; using namespace mozilla::a11y;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsISupports // nsISupports and cycle collection
NS_INTERFACE_MAP_BEGIN(xpcAccessibleGeneric) NS_IMPL_CYCLE_COLLECTION_0(xpcAccessibleGeneric)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(xpcAccessibleGeneric)
NS_INTERFACE_MAP_ENTRY(nsIAccessible) NS_INTERFACE_MAP_ENTRY(nsIAccessible)
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAccessibleSelectable, NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIAccessibleSelectable,
mSupportedIfaces & eSelectable) mSupportedIfaces & eSelectable)
@ -22,30 +24,8 @@ NS_INTERFACE_MAP_BEGIN(xpcAccessibleGeneric)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessible) NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessible)
NS_INTERFACE_MAP_END NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(xpcAccessibleGeneric) NS_IMPL_CYCLE_COLLECTING_ADDREF(xpcAccessibleGeneric)
NS_IMPL_RELEASE(xpcAccessibleGeneric) NS_IMPL_CYCLE_COLLECTING_RELEASE(xpcAccessibleGeneric)
xpcAccessibleGeneric::~xpcAccessibleGeneric()
{
if (mIntl.IsNull()) {
return;
}
xpcAccessibleDocument* xpcDoc = nullptr;
if (mIntl.IsAccessible()) {
Accessible* acc = mIntl.AsAccessible();
if (!acc->IsDoc() && !acc->IsApplication()) {
xpcDoc = GetAccService()->GetXPCDocument(acc->Document());
xpcDoc->NotifyOfShutdown(acc);
}
} else {
ProxyAccessible* proxy = mIntl.AsProxy();
if (!proxy->IsDoc()) {
xpcDoc = GetAccService()->GetXPCDocument(proxy->Document());
xpcDoc->NotifyOfShutdown(proxy);
}
}
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// nsIAccessible // nsIAccessible

View File

@ -41,7 +41,8 @@ public:
xpcAccessibleGeneric(ProxyAccessible* aProxy, uint8_t aInterfaces) : xpcAccessibleGeneric(ProxyAccessible* aProxy, uint8_t aInterfaces) :
mIntl(aProxy), mSupportedIfaces(aInterfaces) {} mIntl(aProxy), mSupportedIfaces(aInterfaces) {}
NS_DECL_ISUPPORTS NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(xpcAccessibleGeneric, nsIAccessible)
// nsIAccessible // nsIAccessible
virtual Accessible* ToInternalAccessible() const final override; virtual Accessible* ToInternalAccessible() const final override;
@ -50,7 +51,7 @@ public:
virtual void Shutdown(); virtual void Shutdown();
protected: protected:
virtual ~xpcAccessibleGeneric(); virtual ~xpcAccessibleGeneric() {}
AccessibleOrProxy mIntl; AccessibleOrProxy mIntl;