From ed9b031c43a27be2a4ed5b32563dbef8904a1e17 Mon Sep 17 00:00:00 2001 From: Johnny Stenback Date: Fri, 11 Jul 2008 14:44:59 -0700 Subject: [PATCH] Landing fix for bug 442066. Make XPCWrappedJS destruction threadsafe. Patch by bruno@flock.com and manish@flock.com, r+sr=jst@ --- js/src/xpconnect/src/xpcwrappedjs.cpp | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/js/src/xpconnect/src/xpcwrappedjs.cpp b/js/src/xpconnect/src/xpcwrappedjs.cpp index 8c9fe5d13ba..f4b47997c7a 100644 --- a/js/src/xpconnect/src/xpcwrappedjs.cpp +++ b/js/src/xpconnect/src/xpcwrappedjs.cpp @@ -227,6 +227,10 @@ nsXPCWrappedJS::Release(void) { NS_PRECONDITION(0 != mRefCnt, "dup release"); + // need to take the map lock here to prevent GetNewOrUsed from trying + // to reuse a wrapper on one thread while it's being destroyed on another + XPCAutoLock lock(nsXPConnect::GetRuntime()->GetMapLock()); + do_decrement: nsrefcnt cnt = (nsrefcnt) PR_AtomicDecrement((PRInt32*)&mRefCnt); @@ -323,21 +327,23 @@ nsXPCWrappedJS::GetNewOrUsed(XPCCallContext& ccx, if(!rootJSObj) goto return_wrapper; - // look for the root wrapper + // look for the root wrapper, and if found, hold the map lock until + // we've added our ref to prevent another thread from destroying it + // under us { // scoped lock XPCAutoLock lock(rt->GetMapLock()); root = map->Find(rootJSObj); - } - if(root) - { - if((nsnull != (wrapper = root->Find(aIID))) || - (nsnull != (wrapper = root->FindInherited(aIID)))) + if(root) { - NS_ADDREF(wrapper); - goto return_wrapper; + if((nsnull != (wrapper = root->Find(aIID))) || + (nsnull != (wrapper = root->FindInherited(aIID)))) + { + NS_ADDREF(wrapper); + goto return_wrapper; + } } } - else + if(!root) { // build the root wrapper if(rootJSObj == aJSObj) @@ -430,7 +436,7 @@ nsXPCWrappedJS::nsXPCWrappedJS(XPCCallContext& ccx, InitStub(GetClass()->GetIID()); - // intensionally do double addref - see Release(). + // intentionally do double addref - see Release(). NS_ADDREF_THIS(); NS_ADDREF_THIS(); NS_ADDREF(aClass);