Bug 414747: Make BroadcastListener use nsWeakRef rather than strong references, just in case. r/sr=jst b3a=mconnor

This commit is contained in:
jonas@sicking.cc 2008-02-04 15:50:44 -08:00
parent b6c3aaf3e4
commit 919076864b

View File

@ -181,7 +181,7 @@ struct BroadcasterMapEntry : public PLDHashEntryHdr {
};
struct BroadcastListener {
nsCOMPtr<nsIDOMElement> mListener; // [OWNING], and traversed
nsWeakPtr mListener;
nsCOMPtr<nsIAtom> mAttribute;
};
@ -323,34 +323,12 @@ TraverseObservers(nsIURI* aKey, nsIObserver* aData, void* aContext)
return PL_DHASH_NEXT;
}
static PLDHashOperator PR_CALLBACK
TraverseBroadcasters(PLDHashTable* aTable, PLDHashEntryHdr* aEntry,
PRUint32 aNumber, void* aContext)
{
BroadcasterMapEntry* entry =
static_cast<BroadcasterMapEntry*>(aEntry);
nsCycleCollectionTraversalCallback *cb =
static_cast<nsCycleCollectionTraversalCallback*>(aContext);
for (PRInt32 i = entry->mListeners.Count() - 1; i >= 0; --i) {
BroadcastListener *listener =
(BroadcastListener *)entry->mListeners[i];
cb->NoteXPCOMChild(listener->mListener);
}
return PL_DHASH_NEXT;
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXULDocument, nsXMLDocument)
// XXX tmp->mForwardReferences?
// XXX tmp->mContextStack?
tmp->mElementMap.Enumerate(TraverseElement, &cb);
if (tmp->mBroadcasterMap)
PL_DHashTableEnumerate(tmp->mBroadcasterMap, TraverseBroadcasters, &cb);
// An element will only have a template builder as long as it's in the
// document, so we'll traverse the table here instead of from the element.
if (tmp->mTemplateBuilderTable)
@ -795,13 +773,13 @@ nsXULDocument::AddBroadcastListenerFor(nsIDOMElement* aBroadcaster,
BroadcasterMapEntry* entry =
static_cast<BroadcasterMapEntry*>
(PL_DHashTableOperate(mBroadcasterMap, aBroadcaster,
PL_DHASH_LOOKUP));
PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_FREE(entry)) {
entry =
static_cast<BroadcasterMapEntry*>
(PL_DHashTableOperate(mBroadcasterMap, aBroadcaster,
PL_DHASH_ADD));
PL_DHASH_ADD));
if (! entry)
return NS_ERROR_OUT_OF_MEMORY;
@ -820,7 +798,9 @@ nsXULDocument::AddBroadcastListenerFor(nsIDOMElement* aBroadcaster,
for (PRInt32 i = entry->mListeners.Count() - 1; i >= 0; --i) {
bl = static_cast<BroadcastListener*>(entry->mListeners[i]);
if ((bl->mListener == aListener) && (bl->mAttribute == attr))
nsCOMPtr<nsIDOMElement> blListener = do_QueryReferent(bl->mListener);
if ((blListener == aListener) && (bl->mAttribute == attr))
return NS_OK;
}
@ -828,7 +808,7 @@ nsXULDocument::AddBroadcastListenerFor(nsIDOMElement* aBroadcaster,
if (! bl)
return NS_ERROR_OUT_OF_MEMORY;
bl->mListener = aListener;
bl->mListener = do_GetWeakReference(aListener);
bl->mAttribute = attr;
entry->mListeners.AppendElement(bl);
@ -850,7 +830,7 @@ nsXULDocument::RemoveBroadcastListenerFor(nsIDOMElement* aBroadcaster,
BroadcasterMapEntry* entry =
static_cast<BroadcasterMapEntry*>
(PL_DHashTableOperate(mBroadcasterMap, aBroadcaster,
PL_DHASH_LOOKUP));
PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
nsCOMPtr<nsIAtom> attr = do_GetAtom(aAttr);
@ -858,7 +838,9 @@ nsXULDocument::RemoveBroadcastListenerFor(nsIDOMElement* aBroadcaster,
BroadcastListener* bl =
static_cast<BroadcastListener*>(entry->mListeners[i]);
if ((bl->mListener == aListener) && (bl->mAttribute == attr)) {
nsCOMPtr<nsIDOMElement> blListener = do_QueryReferent(bl->mListener);
if ((blListener == aListener) && (bl->mAttribute == attr)) {
entry->mListeners.RemoveElementAt(i);
delete bl;
@ -967,7 +949,7 @@ nsXULDocument::AttributeChanged(nsIDocument* aDocument,
BroadcasterMapEntry* entry =
static_cast<BroadcasterMapEntry*>
(PL_DHashTableOperate(mBroadcasterMap, domele.get(),
PL_DHASH_LOOKUP));
PL_DHASH_LOOKUP));
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
// We've got listeners: push the value.
@ -983,8 +965,10 @@ nsXULDocument::AttributeChanged(nsIDocument* aDocument,
if ((bl->mAttribute == aAttribute) ||
(bl->mAttribute == nsGkAtoms::_asterix)) {
nsCOMPtr<nsIContent> listener
= do_QueryInterface(bl->mListener);
listenerArray.AppendObject(listener);
= do_QueryReferent(bl->mListener);
if (listener) {
listenerArray.AppendObject(listener);
}
}
}