From 43916a6230a37800a210985ef10dbb83bb5584e2 Mon Sep 17 00:00:00 2001 From: "dougt%netscape.com" Date: Wed, 12 Jan 2000 01:26:11 +0000 Subject: [PATCH] locking nsProxyObject before calling XPT_InvokeByIndex() locking maps for entire GetNewOrUsedClass() process. locking maps while trying to Find an IID off of a Root. locking when removing from RealObjectToProxyObjectMap I am hoping that this will fix some of the SMP problems, namely 21556. r=mccabe. git-svn-id: svn://10.0.0.236/trunk@57484 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/xpcom/proxy/public/nsProxyEvent.h | 6 ++--- mozilla/xpcom/proxy/src/nsProxyEvent.cpp | 18 ++++++++++++--- mozilla/xpcom/proxy/src/nsProxyEventClass.cpp | 21 +++++++++++++----- .../xpcom/proxy/src/nsProxyEventObject.cpp | 5 ++++- mozilla/xpcom/proxy/src/nsProxyEventPrivate.h | 13 ++++++----- .../xpcom/proxy/src/nsProxyObjectManager.cpp | 22 ++++--------------- 6 files changed, 49 insertions(+), 36 deletions(-) diff --git a/mozilla/xpcom/proxy/public/nsProxyEvent.h b/mozilla/xpcom/proxy/public/nsProxyEvent.h index ac0d794e751..eb9b9b3288b 100644 --- a/mozilla/xpcom/proxy/public/nsProxyEvent.h +++ b/mozilla/xpcom/proxy/public/nsProxyEvent.h @@ -95,9 +95,8 @@ public: nsISupports* GetRealObject(); nsIEventQueue* GetQueue(); PRInt32 GetProxyType() const { return mProxyType; } - - + PRLock* GetLock() const { return mLock; } private: @@ -107,7 +106,8 @@ private: nsCOMPtr mRealObject; /* the non-proxy object that this event is referring to. This is a strong ref. */ - + PRLock *mLock; + nsresult convertMiniVariantToVariant(nsXPTMethodInfo * methodInfo, nsXPTCMiniVariant * params, diff --git a/mozilla/xpcom/proxy/src/nsProxyEvent.cpp b/mozilla/xpcom/proxy/src/nsProxyEvent.cpp index 64b06b9ef08..d2d346df01e 100644 --- a/mozilla/xpcom/proxy/src/nsProxyEvent.cpp +++ b/mozilla/xpcom/proxy/src/nsProxyEvent.cpp @@ -36,6 +36,8 @@ #include "nsIEventQueueService.h" #include "nsIThread.h" +#include "nsAutoLock.h" + #include "nsIAtom.h" //hack! Need a way to define a component as threadsafe (ie. sta). static NS_DEFINE_CID(kEventQueueServiceCID, NS_EVENTQUEUESERVICE_CID); @@ -52,6 +54,11 @@ nsProxyObjectCallInfo::nsProxyObjectCallInfo( nsProxyObject* owner, PRUint32 parameterCount, PLEvent *event) { + NS_ASSERTION(owner, "No nsProxyObject!"); + NS_ASSERTION(methodInfo, "No nsXPTMethodInfo!"); + NS_ASSERTION(parameterList, "No parameterList!"); + NS_ASSERTION(event, "No PLEvent!"); + mCompleted = 0; mMethodIndex = methodIndex; mParameterList = parameterList; @@ -61,7 +68,7 @@ nsProxyObjectCallInfo::nsProxyObjectCallInfo( nsProxyObject* owner, mCallersEventQ = nsnull; mOwner = owner; - + RefCountInInterfacePointers(PR_TRUE); if (mOwner->GetProxyType() & PROXY_ASYNC) CopyStrings(PR_TRUE); @@ -204,10 +211,11 @@ nsProxyObject::nsProxyObject() nsProxyObject::nsProxyObject(nsIEventQueue *destQueue, PRInt32 proxyType, nsISupports *realObject) { NS_INIT_REFCNT(); - + mRealObject = realObject; mDestQueue = do_QueryInterface(destQueue); mProxyType = proxyType; + mLock = PR_NewLock(); } @@ -222,6 +230,7 @@ nsProxyObject::nsProxyObject(nsIEventQueue *destQueue, PRInt32 proxyType, const mDestQueue = do_QueryInterface(destQueue); mProxyType = proxyType; + mLock = PR_NewLock(); } nsProxyObject::~nsProxyObject() @@ -231,6 +240,7 @@ nsProxyObject::~nsProxyObject() mRealObject = 0; mDestQueue = 0; + PR_DestroyLock(mLock); } // GetRealObject @@ -432,7 +442,7 @@ void DestroyHandler(PLEvent *self) { nsProxyObjectCallInfo* owner = (nsProxyObjectCallInfo*)PL_GetEventOwner(self); nsProxyObject* proxyObject = owner->GetProxyObject(); - + if (proxyObject == nsnull) return; @@ -456,6 +466,8 @@ void* EventHandler(PLEvent *self) if (proxyObject) { + nsAutoLock lock(proxyObject->GetLock()); + // invoke the magic of xptc... nsresult rv = XPTC_InvokeByIndex( proxyObject->GetRealObject(), info->GetMethodIndex(), diff --git a/mozilla/xpcom/proxy/src/nsProxyEventClass.cpp b/mozilla/xpcom/proxy/src/nsProxyEventClass.cpp index f769b434e86..56654c23880 100644 --- a/mozilla/xpcom/proxy/src/nsProxyEventClass.cpp +++ b/mozilla/xpcom/proxy/src/nsProxyEventClass.cpp @@ -33,7 +33,7 @@ #include "nsIAllocator.h" #include "nsHashtable.h" - +#include "nsAutoLock.h" #include "nsIInterfaceInfoManager.h" #include "xptcall.h" @@ -55,7 +55,12 @@ nsProxyEventClass::GetNewOrUsedClass(REFNSIID aIID) /* find in our hash table */ nsProxyObjectManager *manager = nsProxyObjectManager::GetInstance(); - nsHashtable *iidToClassMap = manager->GetIIDToProxyClassMap(); + if (manager == nsnull) return nsnull; + + // dont need to lock the map, because this is only called + // by nsProxyEventClass::GetNewOrUsed which locks it for us. + + nsHashtable *iidToClassMap = manager->GetIIDToProxyClassMap(); if (iidToClassMap == nsnull) { @@ -64,7 +69,7 @@ nsProxyEventClass::GetNewOrUsedClass(REFNSIID aIID) nsProxyEventClass* clazz = nsnull; nsIDKey key(aIID); - + if(iidToClassMap->Exists(&key)) { clazz = (nsProxyEventClass*) iidToClassMap->Get(&key); @@ -129,7 +134,11 @@ nsProxyEventClass::nsProxyEventClass(REFNSIID aIID, nsIInterfaceInfo* aInfo) nsIDKey key(aIID); nsProxyObjectManager *manager = nsProxyObjectManager::GetInstance(); - nsHashtable *iidToClassMap = manager->GetIIDToProxyClassMap(); + if (manager == nsnull) return; + // dont need to lock the map, because this is only called + // by GetNewOrUsed which locks it for us. + + nsHashtable *iidToClassMap = manager->GetIIDToProxyClassMap(); if (iidToClassMap == nsnull) { @@ -162,7 +171,9 @@ nsProxyEventClass::~nsProxyEventClass() nsIDKey key(mIID); nsProxyObjectManager *manager = nsProxyObjectManager::GetInstance(); - nsHashtable *iidToClassMap = manager->GetIIDToProxyClassMap(); + if (manager == nsnull) return; + nsAutoLock lock(manager->GetMapLock()); + nsHashtable *iidToClassMap = manager->GetIIDToProxyClassMap(); if (iidToClassMap != nsnull) { diff --git a/mozilla/xpcom/proxy/src/nsProxyEventObject.cpp b/mozilla/xpcom/proxy/src/nsProxyEventObject.cpp index adc230d6d11..142657b26de 100644 --- a/mozilla/xpcom/proxy/src/nsProxyEventObject.cpp +++ b/mozilla/xpcom/proxy/src/nsProxyEventObject.cpp @@ -33,6 +33,8 @@ #include "nsIInterfaceInfoManager.h" #include "xptcall.h" +#include "nsAutoLock.h" + static NS_DEFINE_IID(kProxyObject_Identity_Class_IID, NS_PROXYEVENT_IDENTITY_CLASS_IID); #ifdef DEBUG_dougt @@ -143,7 +145,7 @@ nsProxyEventObject::GetNewOrUsedProxy(nsIEventQueue *destQueue, /* get our hash table */ nsProxyObjectManager *manager = nsProxyObjectManager::GetInstance(); if (manager == nsnull) return nsnull; - + nsAutoLock lock(manager->GetMapLock()); nsHashtable *realToProxyMap = manager->GetRealObjectToProxyObjectMap(); if (realToProxyMap == nsnull) return nsnull; @@ -315,6 +317,7 @@ DebugDump("Delete", 0); else { nsProxyObjectManager *manager = nsProxyObjectManager::GetInstance(); + nsAutoLock lock(manager->GetMapLock()); nsHashtable *realToProxyMap = manager->GetRealObjectToProxyObjectMap(); if (realToProxyMap != nsnull && mHashKey.HashValue() != 0) diff --git a/mozilla/xpcom/proxy/src/nsProxyEventPrivate.h b/mozilla/xpcom/proxy/src/nsProxyEventPrivate.h index 5376ce42db5..2a88dfb9a81 100644 --- a/mozilla/xpcom/proxy/src/nsProxyEventPrivate.h +++ b/mozilla/xpcom/proxy/src/nsProxyEventPrivate.h @@ -130,6 +130,8 @@ public: #endif protected: + PRLock *mLock; + nsStringKey mHashKey; nsCOMPtr mClass; @@ -172,7 +174,6 @@ public: void** aProxyObject); - static NS_METHOD Create(nsISupports* outer, const nsIID& aIID, void* *aInstancePtr); nsProxyObjectManager(); @@ -180,14 +181,14 @@ public: static nsProxyObjectManager *GetInstance(); - nsHashtable *GetRealObjectToProxyObjectMap(); - nsHashtable *GetIIDToProxyClassMap(); - + PRLock* GetMapLock() const { return mMapLock; } + nsHashtable* GetRealObjectToProxyObjectMap() const { return mProxyObjectMap;} + nsHashtable* GetIIDToProxyClassMap() const { return mProxyClassMap; } + private: static nsProxyObjectManager* mInstance; - - PRLock *mLock; + PRLock* mMapLock; nsHashtable *mProxyObjectMap; nsHashtable *mProxyClassMap; }; diff --git a/mozilla/xpcom/proxy/src/nsProxyObjectManager.cpp b/mozilla/xpcom/proxy/src/nsProxyObjectManager.cpp index fdccd7a5819..b59fb9c8530 100644 --- a/mozilla/xpcom/proxy/src/nsProxyObjectManager.cpp +++ b/mozilla/xpcom/proxy/src/nsProxyObjectManager.cpp @@ -93,7 +93,8 @@ NS_IMPL_ISUPPORTS1(nsProxyObjectManager, nsIProxyObjectManager) nsProxyObjectManager::nsProxyObjectManager() { NS_INIT_REFCNT(); - + + mMapLock = PR_NewLock(); mProxyClassMap = new nsHashtable(256, PR_TRUE); mProxyObjectMap = new nsHashtable(256, PR_TRUE); } @@ -103,6 +104,8 @@ nsProxyObjectManager::~nsProxyObjectManager() delete mProxyClassMap; delete mProxyObjectMap; nsProxyObjectManager::mInstance = nsnull; + + PR_DestroyLock(mMapLock); } nsProxyObjectManager * @@ -233,23 +236,6 @@ nsProxyObjectManager::GetProxyObject(nsIEventQueue *destQueue, return rv; } - -nsHashtable* -nsProxyObjectManager::GetRealObjectToProxyObjectMap() -{ - NS_VERIFY(mProxyObjectMap, "no hashtable"); - return mProxyObjectMap; -} - -nsHashtable* -nsProxyObjectManager::GetIIDToProxyClassMap() -{ - NS_VERIFY(mProxyClassMap, "no hashtable"); - return mProxyClassMap; -} - - - ///////////////////////////////////////////////////////////////////////// // nsProxyEventFactory /////////////////////////////////////////////////////////////////////////