mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Adding debug support to detect reentrant create instance patterns, r+sr=alecf@netscape.com, b=194568
This commit is contained in:
parent
210e29411b
commit
2ccd3b4f03
@ -88,6 +88,7 @@ PRLogModuleInfo* nsComponentManagerLog = nsnull;
|
||||
|
||||
#if defined(DEBUG)
|
||||
// #define SHOW_DENIED_ON_SHUTDOWN
|
||||
// #define SHOW_CI_ON_EXISTING_SERVICE
|
||||
#endif
|
||||
|
||||
// Loader Types
|
||||
@ -1591,7 +1592,6 @@ nsComponentManagerImpl::GetFactoryEntry(const char *aContractID)
|
||||
{
|
||||
nsFactoryEntry *fe = nsnull;
|
||||
{
|
||||
|
||||
nsAutoMonitor mon(mMon);
|
||||
|
||||
nsContractIDTableEntry* contractIDTableEntry =
|
||||
@ -1816,6 +1816,32 @@ nsComponentManagerImpl::CLSIDToContractID(const nsCID &aClass,
|
||||
return rv;
|
||||
}
|
||||
|
||||
#ifdef XPCOM_CHECK_PENDING_CIDS
|
||||
nsresult
|
||||
nsComponentManagerImpl::AddPendingCID(const nsCID &aClass)
|
||||
{
|
||||
nsAutoMonitor mon(mMon);
|
||||
int max = mPendingCIDs.Count();
|
||||
for (int index = 0; index < max; index++)
|
||||
{
|
||||
nsCID *cidp = (nsCID*) mPendingCIDs.ElementAt(index);
|
||||
NS_ASSERTION(cidp, "Bad CID in pending list");
|
||||
if (cidp->Equals(aClass)) {
|
||||
NS_WARNING("Creation in progress (Reentrant CI - see bug 194568)");
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
}
|
||||
mPendingCIDs.AppendElement((void*)&aClass);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsComponentManagerImpl::RemovePendingCID(const nsCID &aClass)
|
||||
{
|
||||
nsAutoMonitor mon(mMon);
|
||||
mPendingCIDs.RemoveElement((void*)&aClass);
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* CreateInstance()
|
||||
*
|
||||
@ -1850,12 +1876,32 @@ nsComponentManagerImpl::CreateInstance(const nsCID &aClass,
|
||||
}
|
||||
*aResult = nsnull;
|
||||
|
||||
nsFactoryEntry *entry = GetFactoryEntry(aClass);
|
||||
|
||||
if (!entry || entry == kNonExistentContractID)
|
||||
return NS_ERROR_FACTORY_NOT_REGISTERED;
|
||||
|
||||
#ifdef SHOW_CI_ON_EXISTING_SERVICE
|
||||
NS_ASSERTION(!entry->mServiceObject,
|
||||
"You are calling CreateInstance when a service for this CID already exists!");
|
||||
#endif
|
||||
|
||||
nsIFactory *factory = nsnull;
|
||||
nsresult rv = FindFactory(aClass, &factory);
|
||||
nsresult rv = entry->GetFactory(&factory, this);
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
#ifdef XPCOM_CHECK_PENDING_CIDS
|
||||
rv = AddPendingCID(aClass);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
#endif
|
||||
rv = factory->CreateInstance(aDelegate, aIID, aResult);
|
||||
NS_RELEASE(factory);
|
||||
|
||||
#ifdef XPCOM_CHECK_PENDING_CIDS
|
||||
RemovePendingCID(aClass);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1912,12 +1958,32 @@ nsComponentManagerImpl::CreateInstanceByContractID(const char *aContractID,
|
||||
}
|
||||
*aResult = nsnull;
|
||||
|
||||
nsFactoryEntry *entry = GetFactoryEntry(aContractID);
|
||||
|
||||
if (!entry || entry == kNonExistentContractID)
|
||||
return NS_ERROR_FACTORY_NOT_REGISTERED;
|
||||
|
||||
#ifdef SHOW_CI_ON_EXISTING_SERVICE
|
||||
NS_ASSERTION(!entry->mServiceObject,
|
||||
"You are calling CreateInstance when a service for this CID already exist!");
|
||||
#endif
|
||||
|
||||
nsIFactory *factory = nsnull;
|
||||
nsresult rv = FindFactory(aContractID, &factory);
|
||||
nsresult rv = entry->GetFactory(&factory, this);
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
#ifdef XPCOM_CHECK_PENDING_CIDS
|
||||
rv = AddPendingCID(entry->cid);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
#endif
|
||||
rv = factory->CreateInstance(aDelegate, aIID, aResult);
|
||||
NS_RELEASE(factory);
|
||||
|
||||
#ifdef XPCOM_CHECK_PENDING_CIDS
|
||||
RemovePendingCID(entry->cid);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -73,6 +73,10 @@ class nsIServiceManager;
|
||||
// to service mapping and has no cid mapping.
|
||||
#define NS_COMPONENT_TYPE_SERVICE_ONLY -2
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
#define XPCOM_CHECK_PENDING_CIDS
|
||||
#endif
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Array of Loaders and their type strings
|
||||
@ -231,6 +235,14 @@ protected:
|
||||
nsCOMPtr<nsICategoryManager> mCategoryManager;
|
||||
|
||||
PLArenaPool mArena;
|
||||
|
||||
#ifdef XPCOM_CHECK_PENDING_CIDS
|
||||
nsresult AddPendingCID(const nsCID &aClass);
|
||||
void RemovePendingCID(const nsCID &aClass);
|
||||
|
||||
nsVoidArray mPendingCIDs;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -329,6 +341,8 @@ struct nsContractIDTableEntry : public PLDHashEntryHdr {
|
||||
char *mContractID;
|
||||
nsFactoryEntry *mFactoryEntry;
|
||||
};
|
||||
|
||||
|
||||
class AutoRegEntry
|
||||
{
|
||||
public:
|
||||
|
Loading…
Reference in New Issue
Block a user