From 859638354ce4e9d995fdb45778a294ec09044069 Mon Sep 17 00:00:00 2001 From: "dbaron%dbaron.org" Date: Tue, 18 Apr 2006 20:59:28 +0000 Subject: [PATCH] Disconnect and release the event listener manager after removing the entry from the hash table to avoid crashes caused re-entry into hash table code. b=334177 r+sr=jst git-svn-id: svn://10.0.0.236/trunk@194624 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/base/src/nsContentUtils.cpp | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/mozilla/content/base/src/nsContentUtils.cpp b/mozilla/content/base/src/nsContentUtils.cpp index e3524c77c14..887956b7815 100644 --- a/mozilla/content/base/src/nsContentUtils.cpp +++ b/mozilla/content/base/src/nsContentUtils.cpp @@ -203,9 +203,7 @@ public: ~EventListenerManagerMapEntry() { - if (mListenerManager) { - mListenerManager->Disconnect(); - } + NS_ASSERTION(!mListenerManager, "caller must release and disconnect ELM"); } private: @@ -2887,8 +2885,20 @@ void nsContentUtils::RemoveListenerManager(nsIContent *aContent) { if (sEventListenerManagersHash.ops) { - PL_DHashTableOperate(&sEventListenerManagersHash, aContent, - PL_DHASH_REMOVE); + EventListenerManagerMapEntry *entry = + NS_STATIC_CAST(EventListenerManagerMapEntry *, + PL_DHashTableOperate(&sEventListenerManagersHash, aContent, + PL_DHASH_LOOKUP)); + if (PL_DHASH_ENTRY_IS_BUSY(entry)) { + nsCOMPtr 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->Disconnect(); + } + } } }