From 77cb09d7fb3ca8c41fe1b34abcb8f56abccf6ae3 Mon Sep 17 00:00:00 2001 From: "bzbarsky%mit.edu" Date: Sun, 27 Feb 2005 17:24:53 +0000 Subject: [PATCH] Stash our bindings in an array before destroying them, in case someone decides to try to add a binding to the hashtable from a binding destructor. Bug 283698, r+sr=bryner git-svn-id: svn://10.0.0.236/trunk@169947 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/xbl/src/nsBindingManager.cpp | 26 ++++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/mozilla/content/xbl/src/nsBindingManager.cpp b/mozilla/content/xbl/src/nsBindingManager.cpp index 3f97ef4bce7..e0bcfe84af7 100644 --- a/mozilla/content/xbl/src/nsBindingManager.cpp +++ b/mozilla/content/xbl/src/nsBindingManager.cpp @@ -779,20 +779,36 @@ nsBindingManager::ProcessAttachedQueue() } PR_STATIC_CALLBACK(PLDHashOperator) -ExecuteDetachedHandler(nsISupports *aKey, - nsXBLBinding *aBinding, void* aClosure) +AccumulateBindingsToDetach(nsISupports *aKey, nsXBLBinding *aBinding, + void* aVoidArray) { - aBinding->ExecuteDetachedHandler(); + nsVoidArray* arr = NS_STATIC_CAST(nsVoidArray*, aVoidArray); + // Hold an owning reference to this binding, just in case + if (arr->AppendElement(aBinding)) + NS_ADDREF(aBinding); return PL_DHASH_NEXT; } +PR_STATIC_CALLBACK(PRBool) +ExecuteDetachedHandler(void* aBinding, void* aClosure) +{ + NS_PRECONDITION(aBinding, "Null binding in list?"); + nsXBLBinding* binding = NS_STATIC_CAST(nsXBLBinding*, aBinding); + binding->ExecuteDetachedHandler(); + // Drop our ref to the binding now + NS_RELEASE(binding); + return PR_TRUE; +} NS_IMETHODIMP nsBindingManager::ExecuteDetachedHandlers() { // Walk our hashtable of bindings. - if (mBindingTable.IsInitialized()) - mBindingTable.EnumerateRead(ExecuteDetachedHandler, nsnull); + if (mBindingTable.IsInitialized()) { + nsVoidArray bindingsToDetach; + mBindingTable.EnumerateRead(AccumulateBindingsToDetach, &bindingsToDetach); + bindingsToDetach.EnumerateForwards(ExecuteDetachedHandler, nsnull); + } return NS_OK; }