Bug 462497 - nsComponentManagerImpl::HashContractID() reenters mMon; r=benjamin
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -1293,17 +1293,17 @@ out:
nsresult
nsComponentManagerImpl::HashContractID(const char *aContractID,
PRUint32 aContractIDLen,
nsFactoryEntry *fe)
{
if(!aContractID || !aContractIDLen)
return NS_ERROR_NULL_POINTER;
- nsAutoMonitor mon(mMon);
+ NS_ASSERTION(PR_GetMonitorEntryCount(mMon), "called from outside mMon");
nsContractIDTableEntry* contractIDTableEntry =
static_cast<nsContractIDTableEntry*>
(PL_DHashTableOperate(&mContractIDs, aContractID,
PL_DHASH_ADD));
if (!contractIDTableEntry)
return NS_ERROR_OUT_OF_MEMORY;
--- a/xpcom/components/nsComponentManager.h
+++ b/xpcom/components/nsComponentManager.h
@@ -208,16 +208,19 @@ public:
nsresult FindFactory(const char *contractID, PRUint32 aContractIDLen, nsIFactory **aFactory) ;
nsresult LoadFactory(nsFactoryEntry *aEntry, nsIFactory **aFactory);
nsFactoryEntry *GetFactoryEntry(const char *aContractID,
PRUint32 aContractIDLen);
nsFactoryEntry *GetFactoryEntry(const nsCID &aClass);
nsresult SyncComponentsInDir(PRInt32 when, nsIFile *dirSpec);
+
+ // NOTE: HashContractID operates on the hash table with ContractIDs,
+ // for thread-safety it should only be invoked from inside mMon.
nsresult HashContractID(const char *acontractID, PRUint32 aContractIDLen,
nsFactoryEntry *fe_ptr);
void DeleteContractIDEntriesByCID(const nsCID* aClass, nsIFactory* factory);
nsresult AutoRegisterImpl(nsIFile* inDirSpec,
nsCOMArray<nsILocalFile> &aLeftovers,
nsTArray<DeferredModule> &aDeferred);
nsresult AutoRegisterDirectory(nsIFile* aComponentFile,