mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 06:11:37 +00:00
fix for bug 196210, component manager is malloc-happy:
- use custom non-allocating CID formatter when writing out compreg.dat - arena allocate category names and keys - pass around string lengths so we don't keep calling strlen r=dougt
This commit is contained in:
parent
709f264374
commit
8e11ceab33
@ -36,6 +36,8 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#define PL_ARENA_CONST_ALIGN_MASK 7
|
||||
|
||||
#include "nsICategoryManager.h"
|
||||
#include "nsCategoryManager.h"
|
||||
|
||||
@ -46,6 +48,7 @@
|
||||
#include "nsIObserver.h"
|
||||
#include "nsComponentManager.h"
|
||||
#include "nsReadableUtils.h"
|
||||
#include "nsCRT.h"
|
||||
|
||||
#include "nsHashtableEnumerator.h"
|
||||
#include "nsEnumeratorUtils.h"
|
||||
@ -64,6 +67,11 @@
|
||||
// this function is not public yet, hence it is externed here.
|
||||
extern nsresult NS_GetComponentLoaderManager(nsIComponentLoaderManager* *result);
|
||||
|
||||
#define NS_CATEGORYMANAGER_ARENA_SIZE (1024 * 8)
|
||||
|
||||
// pulled in from nsComponentManager.cpp
|
||||
char* ArenaStrndup(const char* s, PRUint32 len, PLArenaPool* aArena);
|
||||
char* ArenaStrdup(const char* s, PLArenaPool* aArena);
|
||||
|
||||
static
|
||||
NS_IMETHODIMP
|
||||
@ -88,41 +96,25 @@ ExtractKeyString( nsHashKey* key, void*, void*, nsISupports** _retval )
|
||||
|
||||
|
||||
|
||||
typedef nsCString LeafNode;
|
||||
|
||||
/*
|
||||
Our interior nodes are hashtables whose elements are |LeafNode|s,
|
||||
and we need a suitable destruction function to register with a
|
||||
given (interior node) hashtable for destroying its (|LeafNode|) elements.
|
||||
*/
|
||||
static
|
||||
PRBool
|
||||
Destroy_LeafNode( nsHashKey*, void* aElement, void* )
|
||||
{
|
||||
delete NS_STATIC_CAST(LeafNode*, aElement);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
|
||||
class CategoryNode
|
||||
: public nsObjectHashtable
|
||||
{
|
||||
public:
|
||||
CategoryNode()
|
||||
: nsObjectHashtable((nsHashtableCloneElementFunc) 0, 0,
|
||||
(nsHashtableEnumFunc) Destroy_LeafNode, 0 )
|
||||
(nsHashtableEnumFunc) 0, 0 )
|
||||
{
|
||||
// Nothing else to do here...
|
||||
}
|
||||
|
||||
LeafNode* find_leaf( const char* );
|
||||
const char* find_leaf( const char* );
|
||||
};
|
||||
|
||||
LeafNode*
|
||||
const char*
|
||||
CategoryNode::find_leaf( const char* aLeafName )
|
||||
{
|
||||
nsCStringKey leafNameKey(aLeafName);
|
||||
return NS_STATIC_CAST(LeafNode*, Get(&leafNameKey));
|
||||
return NS_STATIC_CAST(char*, Get(&leafNameKey));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -160,6 +152,8 @@ class nsCategoryManager
|
||||
|
||||
private:
|
||||
CategoryNode* find_category( const char* );
|
||||
|
||||
PLArenaPool mArena;
|
||||
};
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsCategoryManager, nsICategoryManager)
|
||||
@ -169,10 +163,13 @@ nsCategoryManager::nsCategoryManager()
|
||||
(nsHashtableEnumFunc) Destroy_CategoryNode, 0 )
|
||||
|
||||
{
|
||||
PL_INIT_ARENA_POOL(&mArena, "CategoryManagerArena",
|
||||
NS_CATEGORYMANAGER_ARENA_SIZE);
|
||||
}
|
||||
|
||||
nsCategoryManager::~nsCategoryManager()
|
||||
{
|
||||
PL_FinishArenaPool(&mArena);
|
||||
}
|
||||
|
||||
CategoryNode*
|
||||
@ -196,9 +193,9 @@ nsCategoryManager::GetCategoryEntry( const char *aCategoryName,
|
||||
if (category)
|
||||
{
|
||||
nsCStringKey entryKey(aEntryName);
|
||||
LeafNode* entry = NS_STATIC_CAST(LeafNode*, category->Get(&entryKey));
|
||||
const char* entry = NS_STATIC_CAST(char*, category->Get(&entryKey));
|
||||
if (entry)
|
||||
status = (*_retval = ToNewCString(*entry)) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
status = (*_retval = nsCRT::strdup(entry)) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return status;
|
||||
@ -233,12 +230,15 @@ nsCategoryManager::AddCategoryEntry( const char *aCategoryName,
|
||||
{
|
||||
// That category doesn't exist yet; let's make it.
|
||||
category = new CategoryNode;
|
||||
nsCStringKey categoryNameKey(aCategoryName);
|
||||
|
||||
PRUint32 len = strlen(aCategoryName);
|
||||
char* categoryName = ArenaStrndup(aCategoryName, len, &mArena);
|
||||
nsCStringKey categoryNameKey(categoryName, len, nsCStringKey::NEVER_OWN);
|
||||
Put(&categoryNameKey, category);
|
||||
}
|
||||
|
||||
// See if this entry is already in this category
|
||||
LeafNode* entry = category->find_leaf(aEntryName);
|
||||
const char* entry = category->find_leaf(aEntryName);
|
||||
|
||||
nsresult status = NS_OK;
|
||||
if ( entry )
|
||||
@ -250,7 +250,7 @@ nsCategoryManager::AddCategoryEntry( const char *aCategoryName,
|
||||
{
|
||||
// return the value that we're replacing
|
||||
if ( _retval )
|
||||
*_retval = ToNewCString(*entry);
|
||||
*_retval = nsCRT::strdup(entry);
|
||||
}
|
||||
else
|
||||
status = NS_ERROR_INVALID_ARG; // ...stops us from putting the value in
|
||||
@ -263,13 +263,18 @@ nsCategoryManager::AddCategoryEntry( const char *aCategoryName,
|
||||
if ( NS_SUCCEEDED(status) )
|
||||
{ // it's OK to put a value in
|
||||
|
||||
// don't leak the entry we're replacing (if any)
|
||||
delete entry;
|
||||
// we can't delete the entry because we're
|
||||
// arena-allocated.. just pretend we do this.
|
||||
// delete entry;
|
||||
|
||||
// now put in the new vaentrylue
|
||||
entry = new LeafNode(aValue);
|
||||
nsCStringKey entryNameKey(aEntryName);
|
||||
category->Put(&entryNameKey, entry);
|
||||
// now put in the new value entry
|
||||
entry = ArenaStrdup(aValue, &mArena);
|
||||
|
||||
PRUint32 len = strlen(aEntryName);
|
||||
char* entryName = ArenaStrndup(aEntryName, len, &mArena);
|
||||
|
||||
nsCStringKey entryNameKey(entryName, len, nsCStringKey::NEVER_OWN);
|
||||
category->Put(&entryNameKey, (void*)entry);
|
||||
|
||||
nsCOMPtr<nsIComponentLoaderManager> mgr;
|
||||
NS_GetComponentLoaderManager(getter_AddRefs(mgr));
|
||||
|
@ -38,7 +38,7 @@
|
||||
// CAUTION: Arena align mask needs to be defined before including plarena.h
|
||||
// currently from nsComponentManager.h
|
||||
#define PL_ARENA_CONST_ALIGN_MASK 7
|
||||
#define NS_CM_BLOCK_SIZE (1024)
|
||||
#define NS_CM_BLOCK_SIZE (1024 * 8)
|
||||
|
||||
#include "NSReg.h"
|
||||
#include "nsAutoLock.h"
|
||||
@ -124,6 +124,9 @@ const static char XPCOM_ABSCOMPONENT_PREFIX[] = "abs:";
|
||||
const static char XPCOM_RELCOMPONENT_PREFIX[] = "rel:";
|
||||
const static char XPCOM_GRECOMPONENT_PREFIX[] = "gre:";
|
||||
|
||||
static const char gIDFormat[] =
|
||||
"{%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x}";
|
||||
|
||||
// Nonexistent factory entry
|
||||
// This is used to mark non-existent contractid mappings
|
||||
static nsFactoryEntry * kNonExistentContractID = (nsFactoryEntry*) 1;
|
||||
@ -140,9 +143,21 @@ static nsFactoryEntry * kNonExistentContractID = (nsFactoryEntry*) 1;
|
||||
NS_DEFINE_CID(kEmptyCID, NS_EMPTY_IID);
|
||||
NS_DEFINE_CID(kCategoryManagerCID, NS_CATEGORYMANAGER_CID);
|
||||
|
||||
#define UID_STRING_LENGTH 39
|
||||
|
||||
// Set to true from NS_ShutdownXPCOM.
|
||||
extern PRBool gXPCOMShuttingDown;
|
||||
|
||||
static void GetIDString(const nsID& aCID, char buf[UID_STRING_LENGTH])
|
||||
{
|
||||
PR_snprintf(buf, UID_STRING_LENGTH, gIDFormat,
|
||||
aCID.m0, (PRUint32) aCID.m1, (PRUint32) aCID.m2,
|
||||
(PRUint32) aCID.m3[0], (PRUint32) aCID.m3[1],
|
||||
(PRUint32) aCID.m3[2], (PRUint32) aCID.m3[3],
|
||||
(PRUint32) aCID.m3[4], (PRUint32) aCID.m3[5],
|
||||
(PRUint32) aCID.m3[6], (PRUint32) aCID.m3[7]);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsCreateInstanceFromCategory::operator()(const nsIID& aIID, void** aInstancePtr) const
|
||||
{
|
||||
@ -229,18 +244,23 @@ nsGetServiceFromCategory::operator()(const nsIID& aIID, void** aInstancePtr) con
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Arena helper functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static inline char *
|
||||
ArenaStrdup(const char *s, PLArenaPool *arena)
|
||||
char *
|
||||
ArenaStrndup(const char *s, PRUint32 len, PLArenaPool *arena)
|
||||
{
|
||||
void *mem;
|
||||
// Include trailing null in the len
|
||||
PRInt32 len = strlen(s) + 1;
|
||||
PL_ARENA_ALLOCATE(mem, arena, len);
|
||||
PL_ARENA_ALLOCATE(mem, arena, len+1);
|
||||
if (mem)
|
||||
memcpy(mem, s, len);
|
||||
memcpy(mem, s, len+1);
|
||||
return NS_STATIC_CAST(char *, mem);
|
||||
}
|
||||
|
||||
char*
|
||||
ArenaStrdup(const char *s, PLArenaPool *arena)
|
||||
{
|
||||
return ArenaStrndup(s, strlen(s), arena);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Hashtable Callbacks
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -352,11 +372,12 @@ static PLDHashTableOps contractID_DHashTableOps = {
|
||||
MOZ_DECL_CTOR_COUNTER(nsFactoryEntry)
|
||||
nsFactoryEntry::nsFactoryEntry(const nsCID &aClass,
|
||||
const char *aLocation,
|
||||
PRUint32 locationlen,
|
||||
int aType)
|
||||
: cid(aClass), typeIndex(aType)
|
||||
{
|
||||
// Arena allocate the location string
|
||||
location = ArenaStrdup(aLocation, &nsComponentManagerImpl::gComponentManager->mArena);
|
||||
location = ArenaStrndup(aLocation, locationlen, &nsComponentManagerImpl::gComponentManager->mArena);
|
||||
}
|
||||
|
||||
nsFactoryEntry::nsFactoryEntry(const nsCID &aClass, nsIFactory *aFactory)
|
||||
@ -663,7 +684,8 @@ ConvertContractIDKeyToString(PLDHashTable *table,
|
||||
const nsContractIDTableEntry *entry =
|
||||
NS_REINTERPRET_CAST(const nsContractIDTableEntry *, hdr);
|
||||
|
||||
wrapper->SetData(nsDependentCString(entry->mContractID));
|
||||
wrapper->SetData(nsDependentCString(entry->mContractID,
|
||||
entry->mContractIDLen));
|
||||
*retval = wrapper;
|
||||
NS_ADDREF(*retval);
|
||||
return NS_OK;
|
||||
@ -731,11 +753,11 @@ nsresult nsComponentManagerImpl::Init(void)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// Minimum alpha uses k=3 because nsFactoryTableEntry saves three
|
||||
// Minimum alpha uses k=2 because nsFactoryTableEntry saves two
|
||||
// words compared to what a chained hash table requires.
|
||||
PL_DHashTableSetAlphaBounds(&mFactories,
|
||||
0.875,
|
||||
PL_DHASH_MIN_ALPHA(&mFactories, 3));
|
||||
PL_DHASH_MIN_ALPHA(&mFactories, 2));
|
||||
}
|
||||
|
||||
if (!mContractIDs.ops) {
|
||||
@ -746,11 +768,13 @@ nsresult nsComponentManagerImpl::Init(void)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
// Minimum alpha uses k=2 because nsContractIDTableEntry saves two
|
||||
// words compared to what a chained hash table requires.
|
||||
// Minimum alpha uses k=1 because nsContractIDTableEntry saves one
|
||||
// word compared to what a chained hash table requires.
|
||||
#if 0
|
||||
PL_DHashTableSetAlphaBounds(&mContractIDs,
|
||||
0.875,
|
||||
PL_DHASH_MIN_ALPHA(&mContractIDs, 2));
|
||||
PL_DHASH_MIN_ALPHA(&mContractIDs, 1));
|
||||
#endif
|
||||
}
|
||||
if (mMon == nsnull) {
|
||||
mMon = nsAutoMonitor::NewMonitor("nsComponentManagerImpl");
|
||||
@ -962,12 +986,14 @@ nsComponentManagerImpl::GetInterface(const nsIID & uuid, void **result)
|
||||
#define PERSISTENT_REGISTRY_VERSION_MAJOR 0
|
||||
|
||||
|
||||
AutoRegEntry::AutoRegEntry(const char* name, PRInt64* modDate)
|
||||
AutoRegEntry::AutoRegEntry(const nsACString& name, PRInt64* modDate) :
|
||||
mName(ToNewCString(name)),
|
||||
mNameLen(name.Length()),
|
||||
mData(nsnull),
|
||||
mModDate(*modDate)
|
||||
{
|
||||
mName = PL_strdup(name);
|
||||
mModDate = *modDate;
|
||||
mData = nsnull;
|
||||
}
|
||||
|
||||
AutoRegEntry::~AutoRegEntry()
|
||||
{
|
||||
if (mName) PL_strfree(mName);
|
||||
@ -1103,7 +1129,7 @@ nsComponentManagerImpl::ReadPersistentRegistry()
|
||||
goto out;
|
||||
|
||||
// VersionLiteral
|
||||
if (0 != PL_strcmp(values[0], "Version"))
|
||||
if (!nsDependentCString(values[0], lengths[0]).Equals(NS_LITERAL_CSTRING("Version")))
|
||||
goto out;
|
||||
|
||||
// major
|
||||
@ -1128,8 +1154,9 @@ nsComponentManagerImpl::ReadPersistentRegistry()
|
||||
break;
|
||||
|
||||
PRInt64 a = nsCRT::atoll(values[1]);
|
||||
AutoRegEntry *entry = new AutoRegEntry(values[0], &a);
|
||||
|
||||
AutoRegEntry *entry =
|
||||
new AutoRegEntry(nsDependentCString(values[0], lengths[0]), &a);
|
||||
|
||||
if (!entry)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
@ -1166,8 +1193,8 @@ nsComponentManagerImpl::ReadPersistentRegistry()
|
||||
if (!mem)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsFactoryEntry *entry = new (mem) nsFactoryEntry(aClass, values[4], loadertype);
|
||||
|
||||
nsFactoryEntry *entry = new (mem) nsFactoryEntry(aClass, values[4], lengths[4], loadertype);
|
||||
|
||||
nsFactoryTableEntry* factoryTableEntry =
|
||||
NS_STATIC_CAST(nsFactoryTableEntry*,
|
||||
PL_DHashTableOperate(&mFactories,
|
||||
@ -1212,8 +1239,10 @@ nsComponentManagerImpl::ReadPersistentRegistry()
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!contractIDTableEntry->mContractID)
|
||||
contractIDTableEntry->mContractID = ArenaStrdup(values[0], &mArena);
|
||||
if (!contractIDTableEntry->mContractID) {
|
||||
contractIDTableEntry->mContractID = ArenaStrndup(values[0], lengths[0], &mArena);
|
||||
contractIDTableEntry->mContractIDLen = lengths[0];
|
||||
}
|
||||
|
||||
contractIDTableEntry->mFactoryEntry = cidEntry;
|
||||
}
|
||||
@ -1268,11 +1297,9 @@ ContractIDWriter(PLDHashTable *table,
|
||||
|
||||
PRFileDesc* fd = ((PersistentWriterArgs*)arg)->mFD;
|
||||
|
||||
char* cidString = factoryEntry->cid.ToString();
|
||||
if (cidString) {
|
||||
PR_fprintf(fd, "%s,%s\n", contractID, cidString); // what if this fails?
|
||||
PR_Free(cidString);
|
||||
}
|
||||
char cidString[UID_STRING_LENGTH];
|
||||
GetIDString(factoryEntry->cid, cidString);
|
||||
PR_fprintf(fd, "%s,%s\n", contractID, cidString); // what if this fails?
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
@ -1289,9 +1316,10 @@ ClassIDWriter(PLDHashTable *table,
|
||||
if (factoryEntry->typeIndex < 0)
|
||||
return PL_DHASH_NEXT;
|
||||
|
||||
char* cidString = factoryEntry->cid.ToString();
|
||||
NS_ASSERTION(cidString, "null cidString!");
|
||||
if (!cidString) return PL_DHASH_NEXT;
|
||||
|
||||
char cidString[UID_STRING_LENGTH];
|
||||
GetIDString(factoryEntry->cid, cidString);
|
||||
|
||||
char *contractID = nsnull, *className = nsnull;
|
||||
|
||||
nsCOMPtr<nsIClassInfo> classInfo = do_QueryInterface(factoryEntry->factory);
|
||||
@ -1316,7 +1344,6 @@ ClassIDWriter(PLDHashTable *table,
|
||||
(className ? className : ""),
|
||||
(location ? location : ""));
|
||||
|
||||
PR_Free(cidString);
|
||||
if (contractID)
|
||||
PR_Free(contractID);
|
||||
if (className)
|
||||
@ -1337,7 +1364,7 @@ AutoRegEntryWriter(nsHashKey *aKey, void *aData, void* aClosure)
|
||||
fmt = "%s,%lld,%s\n";
|
||||
else
|
||||
fmt = "%s,%lld\n";
|
||||
PR_fprintf(fd, fmt, entry->GetName(), entry->GetDate(), extraData);
|
||||
PR_fprintf(fd, fmt, entry->GetName().get(), entry->GetDate(), extraData);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
@ -1500,17 +1527,23 @@ out:
|
||||
// Hash Functions
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
nsresult
|
||||
nsComponentManagerImpl::HashContractID(const char *aContractID, const nsCID &aClass, nsFactoryEntry **pfe)
|
||||
nsComponentManagerImpl::HashContractID(const char *aContractID,
|
||||
PRUint32 aContractIDLen,
|
||||
const nsCID &aClass,
|
||||
nsFactoryEntry **pfe)
|
||||
{
|
||||
nsIDKey cidKey(aClass);
|
||||
return HashContractID(aContractID, aClass, cidKey, pfe);
|
||||
return HashContractID(aContractID, aContractIDLen, aClass, cidKey, pfe);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsComponentManagerImpl::HashContractID(const char *aContractID, const nsCID &aClass, nsIDKey &cidKey, nsFactoryEntry **pfe)
|
||||
nsComponentManagerImpl::HashContractID(const char *aContractID,
|
||||
PRUint32 aContractIDLen,
|
||||
const nsCID &aClass,
|
||||
nsIDKey &cidKey, nsFactoryEntry **pfe)
|
||||
{
|
||||
if (!aContractID)
|
||||
if(!aContractID || !aContractIDLen)
|
||||
{
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
@ -1523,7 +1556,7 @@ nsComponentManagerImpl::HashContractID(const char *aContractID, const nsCID &aCl
|
||||
entry = kNonExistentContractID;
|
||||
}
|
||||
|
||||
nsresult rv = HashContractID(aContractID, entry);
|
||||
nsresult rv = HashContractID(aContractID, aContractIDLen, entry);
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
@ -1533,9 +1566,11 @@ nsComponentManagerImpl::HashContractID(const char *aContractID, const nsCID &aCl
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsComponentManagerImpl::HashContractID(const char *aContractID, nsFactoryEntry *fe)
|
||||
nsComponentManagerImpl::HashContractID(const char *aContractID,
|
||||
PRUint32 aContractIDLen,
|
||||
nsFactoryEntry *fe)
|
||||
{
|
||||
if (!aContractID)
|
||||
if(!aContractID || !aContractIDLen)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsAutoMonitor mon(mMon);
|
||||
@ -1549,8 +1584,10 @@ nsComponentManagerImpl::HashContractID(const char *aContractID, nsFactoryEntry *
|
||||
|
||||
NS_ASSERTION(!contractIDTableEntry->mContractID || !strcmp(contractIDTableEntry->mContractID, aContractID), "contractid conflict");
|
||||
|
||||
if (!contractIDTableEntry->mContractID)
|
||||
contractIDTableEntry->mContractID = ArenaStrdup(aContractID, &mArena);
|
||||
if (!contractIDTableEntry->mContractID) {
|
||||
contractIDTableEntry->mContractID = ArenaStrndup(aContractID, aContractIDLen, &mArena);
|
||||
contractIDTableEntry->mContractIDLen = aContractIDLen;
|
||||
}
|
||||
|
||||
contractIDTableEntry->mFactoryEntry = fe;
|
||||
|
||||
@ -1588,7 +1625,8 @@ nsComponentManagerImpl::LoadFactory(nsFactoryEntry *aEntry,
|
||||
}
|
||||
|
||||
nsFactoryEntry *
|
||||
nsComponentManagerImpl::GetFactoryEntry(const char *aContractID)
|
||||
nsComponentManagerImpl::GetFactoryEntry(const char *aContractID,
|
||||
PRUint32 aContractIDLen)
|
||||
{
|
||||
nsFactoryEntry *fe = nsnull;
|
||||
{
|
||||
@ -1610,7 +1648,7 @@ nsComponentManagerImpl::GetFactoryEntry(const char *aContractID)
|
||||
// same mapping over and over again
|
||||
if (!fe) {
|
||||
fe = kNonExistentContractID;
|
||||
HashContractID(aContractID, fe);
|
||||
HashContractID(aContractID, aContractIDLen, fe);
|
||||
}
|
||||
|
||||
return fe;
|
||||
@ -1672,11 +1710,12 @@ nsComponentManagerImpl::FindFactory(const nsCID &aClass,
|
||||
|
||||
nsresult
|
||||
nsComponentManagerImpl::FindFactory(const char *contractID,
|
||||
PRUint32 aContractIDLen,
|
||||
nsIFactory **aFactory)
|
||||
{
|
||||
PR_ASSERT(aFactory != nsnull);
|
||||
|
||||
nsFactoryEntry *entry = GetFactoryEntry(contractID);
|
||||
nsFactoryEntry *entry = GetFactoryEntry(contractID, aContractIDLen);
|
||||
|
||||
if (!entry || entry == kNonExistentContractID)
|
||||
return NS_ERROR_FACTORY_NOT_REGISTERED;
|
||||
@ -1735,8 +1774,8 @@ nsComponentManagerImpl::GetClassObjectByContractID(const char *contractID,
|
||||
}
|
||||
|
||||
PR_ASSERT(aResult != nsnull);
|
||||
|
||||
rv = FindFactory(contractID, getter_AddRefs(factory));
|
||||
|
||||
rv = FindFactory(contractID, strlen(contractID), getter_AddRefs(factory));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = factory->QueryInterface(aIID, aResult);
|
||||
@ -1766,7 +1805,7 @@ nsComponentManagerImpl::ContractIDToClassID(const char *aContractID, nsCID *aCla
|
||||
|
||||
nsresult rv = NS_ERROR_FACTORY_NOT_REGISTERED;
|
||||
|
||||
nsFactoryEntry *fe = GetFactoryEntry(aContractID);
|
||||
nsFactoryEntry *fe = GetFactoryEntry(aContractID, strlen(aContractID));
|
||||
if (fe && fe != kNonExistentContractID) {
|
||||
*aClass = fe->cid;
|
||||
rv = NS_OK;
|
||||
@ -1882,8 +1921,8 @@ nsComponentManagerImpl::CreateInstance(const nsCID &aClass,
|
||||
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!");
|
||||
NS_WARN_IF_FALSE(!entry->mServiceObject,
|
||||
"You are calling CreateInstance when a service for this CID already exists!");
|
||||
#endif
|
||||
|
||||
nsIFactory *factory = nsnull;
|
||||
@ -1958,14 +1997,14 @@ nsComponentManagerImpl::CreateInstanceByContractID(const char *aContractID,
|
||||
}
|
||||
*aResult = nsnull;
|
||||
|
||||
nsFactoryEntry *entry = GetFactoryEntry(aContractID);
|
||||
nsFactoryEntry *entry = GetFactoryEntry(aContractID, strlen(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!");
|
||||
NS_WARN_IF_FALSE(!entry->mServiceObject,
|
||||
"You are calling CreateInstance when a service for this CID already exist!");
|
||||
#endif
|
||||
|
||||
nsIFactory *factory = nsnull;
|
||||
@ -2189,7 +2228,8 @@ nsComponentManagerImpl::RegisterService(const char* aContractID, nsISupports* aS
|
||||
nsAutoMonitor mon(mMon);
|
||||
|
||||
// check to see if we have a factory entry for the service
|
||||
nsFactoryEntry *entry = GetFactoryEntry(aContractID);
|
||||
PRUint32 contractIDLen = strlen(aContractID);
|
||||
nsFactoryEntry *entry = GetFactoryEntry(aContractID, contractIDLen);
|
||||
|
||||
if (entry == kNonExistentContractID)
|
||||
entry = nsnull;
|
||||
@ -2212,8 +2252,12 @@ nsComponentManagerImpl::RegisterService(const char* aContractID, nsISupports* aS
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
if (!contractIDTableEntry->mContractID)
|
||||
contractIDTableEntry->mContractID = ArenaStrdup(aContractID, &mArena);
|
||||
if (!contractIDTableEntry->mContractID) {
|
||||
contractIDTableEntry->mContractID =
|
||||
ArenaStrndup(aContractID, contractIDLen, &mArena);
|
||||
|
||||
contractIDTableEntry->mContractIDLen = contractIDLen;
|
||||
}
|
||||
|
||||
contractIDTableEntry->mFactoryEntry = entry;
|
||||
}
|
||||
@ -2655,7 +2699,7 @@ nsComponentManagerImpl::RegisterFactory(const nsCID &aClass,
|
||||
|
||||
// Update the ContractID->CLSID Map
|
||||
if (aContractID) {
|
||||
nsresult rv = HashContractID(aContractID, entry);
|
||||
nsresult rv = HashContractID(aContractID, strlen(aContractID), entry);
|
||||
if (NS_FAILED(rv)) {
|
||||
PR_LOG(nsComponentManagerLog, PR_LOG_WARNING,
|
||||
("\t\tFactory register succeeded. "
|
||||
@ -2679,8 +2723,13 @@ nsComponentManagerImpl::RegisterComponent(const nsCID &aClass,
|
||||
PRBool aReplace,
|
||||
PRBool aPersist)
|
||||
{
|
||||
return RegisterComponentCommon(aClass, aClassName, aContractID,
|
||||
aPersistentDescriptor, aReplace, aPersist,
|
||||
return RegisterComponentCommon(aClass, aClassName,
|
||||
aContractID,
|
||||
aContractID ? strlen(aContractID) : 0,
|
||||
aPersistentDescriptor,
|
||||
aPersistentDescriptor ?
|
||||
strlen(aPersistentDescriptor) : 0,
|
||||
aReplace, aPersist,
|
||||
nativeComponentType);
|
||||
}
|
||||
|
||||
@ -2694,8 +2743,11 @@ nsComponentManagerImpl::RegisterComponentWithType(const nsCID &aClass,
|
||||
PRBool aPersist,
|
||||
const char *aType)
|
||||
{
|
||||
return RegisterComponentCommon(aClass, aClassName, aContractID,
|
||||
return RegisterComponentCommon(aClass, aClassName,
|
||||
aContractID,
|
||||
aContractID ? strlen(aContractID) : 0,
|
||||
aLocation,
|
||||
aLocation ? strlen(aLocation) : 0,
|
||||
aReplace, aPersist,
|
||||
aType);
|
||||
}
|
||||
@ -2716,7 +2768,9 @@ nsComponentManagerImpl::RegisterComponentSpec(const nsCID &aClass,
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = RegisterComponentWithType(aClass, aClassName, aContractID, aLibrarySpec,
|
||||
rv = RegisterComponentWithType(aClass, aClassName,
|
||||
aContractID,
|
||||
aLibrarySpec,
|
||||
registryName,
|
||||
aReplace, aPersist,
|
||||
nativeComponentType);
|
||||
@ -2747,7 +2801,9 @@ nsresult
|
||||
nsComponentManagerImpl::RegisterComponentCommon(const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aContractID,
|
||||
PRUint32 aContractIDLen,
|
||||
const char *aRegistryName,
|
||||
PRUint32 aRegistryNameLen,
|
||||
PRBool aReplace,
|
||||
PRBool aPersist,
|
||||
const char *aType)
|
||||
@ -2801,7 +2857,9 @@ nsComponentManagerImpl::RegisterComponentCommon(const nsCID &aClass,
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mRegistryDirty = PR_TRUE;
|
||||
entry = new (mem) nsFactoryEntry(aClass, aRegistryName, typeIndex);
|
||||
entry = new (mem) nsFactoryEntry(aClass,
|
||||
aRegistryName, aRegistryNameLen,
|
||||
typeIndex);
|
||||
if (!entry)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
@ -2818,7 +2876,7 @@ nsComponentManagerImpl::RegisterComponentCommon(const nsCID &aClass,
|
||||
|
||||
// Update the ContractID->CLSID Map
|
||||
if (contractID) {
|
||||
rv = HashContractID(contractID, entry);
|
||||
rv = HashContractID(contractID, aContractIDLen, entry);
|
||||
if (NS_FAILED(rv)) {
|
||||
PR_LOG(nsComponentManagerLog, PR_LOG_ERROR,
|
||||
("\t\tHashContractID(%s) FAILED\n", contractID));
|
||||
@ -3436,7 +3494,7 @@ NS_IMETHODIMP
|
||||
nsComponentManagerImpl::IsContractIDRegistered(const char *aClass,
|
||||
PRBool *_retval)
|
||||
{
|
||||
nsFactoryEntry *entry = GetFactoryEntry(aClass);
|
||||
nsFactoryEntry *entry = GetFactoryEntry(aClass, strlen(aClass));
|
||||
|
||||
if (!entry || entry == kNonExistentContractID)
|
||||
*_retval = PR_FALSE;
|
||||
|
@ -158,24 +158,30 @@ protected:
|
||||
nsresult RegisterComponentCommon(const nsCID &aClass,
|
||||
const char *aClassName,
|
||||
const char *aContractID,
|
||||
PRUint32 aContractIDLen,
|
||||
const char *aRegistryName,
|
||||
PRUint32 aRegistryNameLen,
|
||||
PRBool aReplace, PRBool aPersist,
|
||||
const char *aType);
|
||||
nsresult GetLoaderForType(int aType,
|
||||
nsIComponentLoader **aLoader);
|
||||
nsresult FindFactory(const char *contractID, nsIFactory **aFactory) ;
|
||||
nsresult FindFactory(const char *contractID, PRUint32 aContractIDLen, nsIFactory **aFactory) ;
|
||||
nsresult LoadFactory(nsFactoryEntry *aEntry, nsIFactory **aFactory);
|
||||
|
||||
nsFactoryEntry *GetFactoryEntry(const char *aContractID);
|
||||
nsFactoryEntry *GetFactoryEntry(const char *aContractID,
|
||||
PRUint32 aContractIDLen);
|
||||
nsFactoryEntry *GetFactoryEntry(const nsCID &aClass);
|
||||
nsFactoryEntry *GetFactoryEntry(const nsCID &aClass, nsIDKey &cidKey);
|
||||
|
||||
nsresult SyncComponentsInDir(PRInt32 when, nsIFile *dirSpec);
|
||||
nsresult SelfRegisterDll(nsDll *dll);
|
||||
nsresult SelfUnregisterDll(nsDll *dll);
|
||||
nsresult HashContractID(const char *acontractID, nsFactoryEntry *fe_ptr);
|
||||
nsresult HashContractID(const char *acontractID, const nsCID &aClass, nsFactoryEntry **fe_ptr = NULL);
|
||||
nsresult HashContractID(const char *acontractID, const nsCID &aClass, nsIDKey &cidKey, nsFactoryEntry **fe_ptr = NULL);
|
||||
nsresult HashContractID(const char *acontractID, PRUint32 aContractIDLen,
|
||||
nsFactoryEntry *fe_ptr);
|
||||
nsresult HashContractID(const char *acontractID, PRUint32 aContractIDLen,
|
||||
const nsCID &aClass, nsFactoryEntry **fe_ptr = NULL);
|
||||
nsresult HashContractID(const char *acontractID, PRUint32 aContractIDLen,
|
||||
const nsCID &aClass, nsIDKey &cidKey, nsFactoryEntry **fe_ptr = NULL);
|
||||
|
||||
void DeleteContractIDEntriesByCID(const nsCID* aClass, const char*registryName);
|
||||
void DeleteContractIDEntriesByCID(const nsCID* aClass, nsIFactory* factory);
|
||||
@ -293,7 +299,8 @@ protected:
|
||||
|
||||
class nsFactoryEntry {
|
||||
public:
|
||||
nsFactoryEntry(const nsCID &aClass, const char *location, int aType);
|
||||
nsFactoryEntry(const nsCID &aClass,
|
||||
const char *location, PRUint32 locationlen, int aType);
|
||||
nsFactoryEntry(const nsCID &aClass, nsIFactory *aFactory);
|
||||
~nsFactoryEntry();
|
||||
|
||||
@ -324,11 +331,12 @@ public:
|
||||
}
|
||||
|
||||
nsCID cid;
|
||||
char *location;
|
||||
nsCOMPtr<nsIFactory> factory;
|
||||
// This is an index into the mLoaderData array that holds the type string and the loader
|
||||
int typeIndex;
|
||||
nsCOMPtr<nsISupports> mServiceObject;
|
||||
|
||||
char* location;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -339,6 +347,7 @@ struct nsFactoryTableEntry : public PLDHashEntryHdr {
|
||||
|
||||
struct nsContractIDTableEntry : public PLDHashEntryHdr {
|
||||
char *mContractID;
|
||||
PRUint32 mContractIDLen;
|
||||
nsFactoryEntry *mFactoryEntry;
|
||||
};
|
||||
|
||||
@ -346,10 +355,11 @@ struct nsContractIDTableEntry : public PLDHashEntryHdr {
|
||||
class AutoRegEntry
|
||||
{
|
||||
public:
|
||||
AutoRegEntry(const char* name, PRInt64* modDate);
|
||||
AutoRegEntry(const nsACString& name, PRInt64* modDate);
|
||||
virtual ~AutoRegEntry();
|
||||
|
||||
char* GetName() {return mName;}
|
||||
const nsDependentCString GetName()
|
||||
{ return nsDependentCString(mName, mNameLen); }
|
||||
PRInt64 GetDate() {return mModDate;}
|
||||
void SetDate(PRInt64 *date) { mModDate = *date;}
|
||||
PRBool Modified(PRInt64 *date);
|
||||
@ -361,6 +371,7 @@ public:
|
||||
|
||||
private:
|
||||
char* mName;
|
||||
PRUint32 mNameLen;
|
||||
char* mData;
|
||||
PRInt64 mModDate;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user