diff --git a/mozilla/extensions/java/xpcom/nsJavaWrapper.cpp b/mozilla/extensions/java/xpcom/nsJavaWrapper.cpp index 000f2c3a47e..214f621e1e2 100644 --- a/mozilla/extensions/java/xpcom/nsJavaWrapper.cpp +++ b/mozilla/extensions/java/xpcom/nsJavaWrapper.cpp @@ -1301,25 +1301,32 @@ JAVAPROXY_NATIVE(finalizeProxy) (JNIEnv *env, jclass that, jobject aJavaProxy) // Due to Java's garbage collection, this finalize statement may get called // after FreeJavaGlobals(). So check to make sure that everything is still // initialized. - if (gJavaXPCOMMonitor) { - nsAutoMonitor mon(gJavaXPCOMMonitor); + if (gJavaXPCOMLock) { + nsAutoLock lock(gJavaXPCOMLock); - // Get native XPCOM instance - void* xpcom_obj; - nsresult rv = GetXPCOMInstFromProxy(env, aJavaProxy, &xpcom_obj); - if (NS_SUCCEEDED(rv)) { - JavaXPCOMInstance* inst = NS_STATIC_CAST(JavaXPCOMInstance*, xpcom_obj); -#ifdef DEBUG_JAVAXPCOM - xpcom_addr = NS_REINTERPRET_CAST(PRUint32, inst->GetInstance()); -#endif - nsIID* iid; - rv = inst->InterfaceInfo()->GetInterfaceIID(&iid); + // If may be possible for the lock to be acquired here when FreeGlobals is + // in the middle of running. If so, then this thread will sleep until + // FreeGlobals releases its lock. At that point, we resume this thread + // here, but JavaXPCOM may no longer be initialized. So we need to check + // that everything is legit after acquiring the lock. + if (gJavaXPCOMInitialized) { + // Get native XPCOM instance + void* xpcom_obj; + nsresult rv = GetXPCOMInstFromProxy(env, aJavaProxy, &xpcom_obj); if (NS_SUCCEEDED(rv)) { - rv = gNativeToJavaProxyMap->Remove(env, inst->GetInstance(), *iid); - nsMemory::Free(iid); + JavaXPCOMInstance* inst = NS_STATIC_CAST(JavaXPCOMInstance*, xpcom_obj); +#ifdef DEBUG_JAVAXPCOM + xpcom_addr = NS_REINTERPRET_CAST(PRUint32, inst->GetInstance()); +#endif + nsIID* iid; + rv = inst->InterfaceInfo()->GetInterfaceIID(&iid); + if (NS_SUCCEEDED(rv)) { + rv = gNativeToJavaProxyMap->Remove(env, inst->GetInstance(), *iid); + nsMemory::Free(iid); + } + NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to RemoveJavaProxy"); + delete inst; } - NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to RemoveJavaProxy"); - delete inst; } } diff --git a/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp b/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp index 9854de8c43d..a1c873cc17e 100644 --- a/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp +++ b/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.cpp @@ -89,7 +89,8 @@ jmethodID proxyToStringMID = nsnull; NativeToJavaProxyMap* gNativeToJavaProxyMap = nsnull; JavaToXPTCStubMap* gJavaToXPTCStubMap = nsnull; -PRMonitor* gJavaXPCOMMonitor = nsnull; +PRBool gJavaXPCOMInitialized = PR_FALSE; +PRLock* gJavaXPCOMLock = nsnull; /****************************** @@ -98,7 +99,7 @@ PRMonitor* gJavaXPCOMMonitor = nsnull; PRBool InitializeJavaGlobals(JNIEnv *env) { - if (gJavaXPCOMMonitor) + if (gJavaXPCOMInitialized) return PR_TRUE; jclass clazz; @@ -244,7 +245,8 @@ InitializeJavaGlobals(JNIEnv *env) goto init_error; } - gJavaXPCOMMonitor = nsAutoMonitor::NewMonitor("Javaconnect Monitor"); + gJavaXPCOMLock = PR_NewLock(); + gJavaXPCOMInitialized = PR_TRUE; return PR_TRUE; init_error: @@ -260,7 +262,13 @@ init_error: void FreeJavaGlobals(JNIEnv* env) { - PR_EnterMonitor(gJavaXPCOMMonitor); + PR_Lock(gJavaXPCOMLock); + + // null out global lock so no one else can use it + PRLock* tempLock = gJavaXPCOMLock; + gJavaXPCOMLock = nsnull; + + gJavaXPCOMInitialized = PR_FALSE; // Free the mappings first, since that process depends on some of the Java // globals that are freed later. @@ -325,9 +333,8 @@ FreeJavaGlobals(JNIEnv* env) xpcomJavaProxyClass = nsnull; } - PR_ExitMonitor(gJavaXPCOMMonitor); - nsAutoMonitor::DestroyMonitor(gJavaXPCOMMonitor); - gJavaXPCOMMonitor = nsnull; + PR_Unlock(tempLock); + PR_DestroyLock(tempLock); } @@ -402,7 +409,8 @@ DestroyJavaProxyMappingEnum(PLDHashTable* aTable, PLDHashEntryHdr* aHeader, nsresult NativeToJavaProxyMap::Destroy(JNIEnv* env) { - nsAutoMonitor mon(gJavaXPCOMMonitor); + // This is only called from FreeGlobals(), which already holds the lock. + // nsAutoLock lock(gJavaXPCOMLock); PL_DHashTableEnumerate(mHashTable, DestroyJavaProxyMappingEnum, env); PL_DHashTableDestroy(mHashTable); @@ -415,7 +423,7 @@ nsresult NativeToJavaProxyMap::Add(JNIEnv* env, nsISupports* aXPCOMObject, const nsIID& aIID, jobject aProxy) { - nsAutoMonitor mon(gJavaXPCOMMonitor); + nsAutoLock lock(gJavaXPCOMLock); Entry* e = NS_STATIC_CAST(Entry*, PL_DHashTableOperate(mHashTable, aXPCOMObject, @@ -450,7 +458,7 @@ NativeToJavaProxyMap::Find(JNIEnv* env, nsISupports* aNativeObject, if (!aResult) return NS_ERROR_FAILURE; - nsAutoMonitor mon(gJavaXPCOMMonitor); + nsAutoLock lock(gJavaXPCOMLock); *aResult = nsnull; Entry* e = NS_STATIC_CAST(Entry*, PL_DHashTableOperate(mHashTable, @@ -485,7 +493,8 @@ nsresult NativeToJavaProxyMap::Remove(JNIEnv* env, nsISupports* aNativeObject, const nsIID& aIID) { - nsAutoMonitor mon(gJavaXPCOMMonitor); + // This is only called from finalizeProxy(), which already holds the lock. + // nsAutoLock lock(gJavaXPCOMLock); Entry* e = NS_STATIC_CAST(Entry*, PL_DHashTableOperate(mHashTable, aNativeObject, @@ -557,7 +566,8 @@ DestroyXPTCMappingEnum(PLDHashTable* aTable, PLDHashEntryHdr* aHeader, nsresult JavaToXPTCStubMap::Destroy() { - nsAutoMonitor mon(gJavaXPCOMMonitor); + // This is only called from FreeGlobals(), which already holds the lock. + // nsAutoLock lock(gJavaXPCOMLock); PL_DHashTableEnumerate(mHashTable, DestroyXPTCMappingEnum, nsnull); PL_DHashTableDestroy(mHashTable); @@ -569,7 +579,7 @@ JavaToXPTCStubMap::Destroy() nsresult JavaToXPTCStubMap::Add(JNIEnv* env, jobject aJavaObject, nsJavaXPTCStub* aProxy) { - nsAutoMonitor mon(gJavaXPCOMMonitor); + nsAutoLock lock(gJavaXPCOMLock); jint hash = env->CallIntMethod(aJavaObject, hashCodeMID); Entry* e = NS_STATIC_CAST(Entry*, PL_DHashTableOperate(mHashTable, @@ -606,7 +616,7 @@ JavaToXPTCStubMap::Find(JNIEnv* env, jobject aJavaObject, const nsIID& aIID, if (!aResult) return NS_ERROR_FAILURE; - nsAutoMonitor mon(gJavaXPCOMMonitor); + nsAutoLock lock(gJavaXPCOMLock); *aResult = nsnull; jint hash = env->CallIntMethod(aJavaObject, hashCodeMID); @@ -637,8 +647,6 @@ JavaToXPTCStubMap::Find(JNIEnv* env, jobject aJavaObject, const nsIID& aIID, nsresult JavaToXPTCStubMap::Remove(JNIEnv* env, jobject aJavaObject) { - nsAutoMonitor mon(gJavaXPCOMMonitor); - jint hash = env->CallIntMethod(aJavaObject, hashCodeMID); PL_DHashTableOperate(mHashTable, NS_INT32_TO_PTR(hash), PL_DHASH_REMOVE); @@ -702,8 +710,6 @@ GetNewOrUsedJavaObject(JNIEnv* env, nsISupports* aXPCOMObject, return NS_OK; } - nsAutoMonitor mon(gJavaXPCOMMonitor); - // Get associated Java object from hash table rv = gNativeToJavaProxyMap->Find(env, aXPCOMObject, aIID, aResult); if (NS_FAILED(rv)) @@ -751,8 +757,6 @@ GetNewOrUsedXPCOMObject(JNIEnv* env, jobject aJavaObject, const nsIID& aIID, } } - nsAutoMonitor mon(gJavaXPCOMMonitor); - *aIsXPTCStub = PR_TRUE; nsJavaXPTCStub* stub; diff --git a/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.h b/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.h index 73597643a4b..5b2011431c1 100644 --- a/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.h +++ b/mozilla/extensions/java/xpcom/nsJavaXPCOMBindingUtils.h @@ -113,7 +113,9 @@ extern JavaToXPTCStubMap* gJavaToXPTCStubMap; // The Java garbage collector runs in a separate thread. Since it calls the // finalizeProxy() function in nsJavaWrapper.cpp, we need to make sure that // all the structures touched by finalizeProxy() are multithread aware. -extern PRMonitor* gJavaXPCOMMonitor; +extern PRLock* gJavaXPCOMLock; + +extern PRBool gJavaXPCOMInitialized; /** * Initialize global structures used by Javaconnect. diff --git a/mozilla/extensions/java/xpcom/nsJavaXPTCStub.cpp b/mozilla/extensions/java/xpcom/nsJavaXPTCStub.cpp index f357418c59d..5ed8f952b30 100644 --- a/mozilla/extensions/java/xpcom/nsJavaXPTCStub.cpp +++ b/mozilla/extensions/java/xpcom/nsJavaXPTCStub.cpp @@ -171,7 +171,7 @@ nsJavaXPTCStub::Destroy() delete (nsJavaXPTCStub*) mChildren[i]; } - if (gJavaXPCOMMonitor) { // if Javaconnect is still initialized + if (gJavaXPCOMInitialized) { gJavaToXPTCStubMap->Remove(mJavaEnv, mJavaStrongRef); } }