Disconnect and release the event listener manager after removing the entry from the hash table to avoid crashes caused by re-entry into hash table code. b=334177 r+sr=jst a=dveditz
git-svn-id: svn://10.0.0.236/branches/MOZILLA_1_8_0_BRANCH@194994 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -65,8 +65,22 @@ nsGenericDOMDataNode::nsGenericDOMDataNode(nsIDocument *aDocument)
|
||||
nsGenericDOMDataNode::~nsGenericDOMDataNode()
|
||||
{
|
||||
if (CouldHaveEventListenerManager()) {
|
||||
PL_DHashTableOperate(&nsGenericElement::sEventListenerManagersHash,
|
||||
this, PL_DHASH_REMOVE);
|
||||
EventListenerManagerMapEntry *entry =
|
||||
NS_STATIC_CAST(EventListenerManagerMapEntry *,
|
||||
PL_DHashTableOperate(&nsGenericElement::
|
||||
sEventListenerManagersHash, this,
|
||||
PL_DHASH_LOOKUP));
|
||||
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
|
||||
nsCOMPtr<nsIEventListenerManager> listenerManager;
|
||||
listenerManager.swap(entry->mListenerManager);
|
||||
// Remove the entry and *then* do operations that could cause further
|
||||
// modification of sEventListenerManagersHash. See bug 334177.
|
||||
PL_DHashTableRawRemove(&nsGenericElement::
|
||||
sEventListenerManagersHash, entry);
|
||||
if (listenerManager) {
|
||||
listenerManager->SetListenerTarget(nsnull);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (CouldHaveRangeList()) {
|
||||
|
||||
@@ -883,21 +883,23 @@ nsGenericElement::~nsGenericElement()
|
||||
}
|
||||
|
||||
if (HasEventListenerManager()) {
|
||||
#ifdef DEBUG
|
||||
{
|
||||
EventListenerManagerMapEntry *entry =
|
||||
NS_STATIC_CAST(EventListenerManagerMapEntry *,
|
||||
PL_DHashTableOperate(&sEventListenerManagersHash, this,
|
||||
PL_DHASH_LOOKUP));
|
||||
|
||||
if (PL_DHASH_ENTRY_IS_FREE(entry)) {
|
||||
NS_ERROR("Huh, our bit says we have a listener manager list, "
|
||||
EventListenerManagerMapEntry *entry =
|
||||
NS_STATIC_CAST(EventListenerManagerMapEntry *,
|
||||
PL_DHashTableOperate(&sEventListenerManagersHash, this,
|
||||
PL_DHASH_LOOKUP));
|
||||
NS_ASSERTION(!PL_DHASH_ENTRY_IS_FREE(entry),
|
||||
"Huh, our bit says we have a listener manager list, "
|
||||
"but there's nothing in the hash!?!!");
|
||||
if (PL_DHASH_ENTRY_IS_BUSY(entry)) {
|
||||
nsCOMPtr<nsIEventListenerManager> listenerManager;
|
||||
listenerManager.swap(entry->mListenerManager);
|
||||
// Remove the entry and *then* do operations that could cause further
|
||||
// modification of sEventListenerManagersHash. See bug 334177.
|
||||
PL_DHashTableRawRemove(&sEventListenerManagersHash, entry);
|
||||
if (listenerManager) {
|
||||
listenerManager->SetListenerTarget(nsnull);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
PL_DHashTableOperate(&sEventListenerManagersHash, this, PL_DHASH_REMOVE);
|
||||
}
|
||||
|
||||
if (HasDOMSlots()) {
|
||||
|
||||
@@ -228,9 +228,7 @@ public:
|
||||
|
||||
~EventListenerManagerMapEntry()
|
||||
{
|
||||
if (mListenerManager) {
|
||||
mListenerManager->SetListenerTarget(nsnull);
|
||||
}
|
||||
NS_ASSERTION(!mListenerManager, "caller must release and disconnect ELM");
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Reference in New Issue
Block a user