Implemented dll enumeration and prepopulation. Improves startup performance.

git-svn-id: svn://10.0.0.236/trunk@46953 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
dp%netscape.com
1999-09-11 14:49:55 +00:00
parent 99bb341f6e
commit 1f56932ae0
2 changed files with 85 additions and 68 deletions

View File

@@ -104,7 +104,7 @@ nsNativeComponentLoader::GetFactory(const nsIID & aCID,
/* Should this all live in xcDll? */
nsDll *dll;
rv = CreateDll(nsnull, aLocation, &dll);
rv = CreateDll(nsnull, aLocation, 0, 0, &dll);
if (NS_FAILED(rv))
return rv;
@@ -218,6 +218,48 @@ nsNativeComponentLoader::Init(nsIComponentManager *aCompMgr, nsISupports *aReg)
}
}
// Read in all dll entries and populate the mDllStore
nsCOMPtr<nsIEnumerator> dllEnum;
rv = mRegistry->EnumerateSubtrees( mXPCOMKey, getter_AddRefs(dllEnum));
if (NS_FAILED(rv)) return rv;
rv = dllEnum->First();
for (; NS_SUCCEEDED(rv) && !dllEnum->IsDone(); (rv = dllEnum->Next()))
{
nsCOMPtr<nsISupports> base;
rv = dllEnum->CurrentItem(getter_AddRefs(base));
if (NS_FAILED(rv)) continue;
// Get specific interface.
nsIID nodeIID = NS_IREGISTRYNODE_IID;
nsCOMPtr<nsIRegistryNode> node;
rv = base->QueryInterface( nodeIID, getter_AddRefs(node) );
if (NS_FAILED(rv)) continue;
// Get library name
char *library = NULL;
rv = node->GetName(&library);
if (NS_FAILED(rv)) continue;
autoStringFree delete_library(library, autoStringFree::nsCRT_String_Delete);
// Get key associated with library
nsIRegistry::Key libKey;
rv = node->GetKey(&libKey);
if (NS_FAILED(rv)) continue;
// Create nsDll with this name
nsDll *dll = NULL;
PRUint32 lastModTime = 0;
PRUint32 fileSize = 0;
GetRegistryDllInfo(libKey, &lastModTime, &fileSize);
rv = CreateDll(NULL, library, lastModTime, fileSize, &dll);
if (NS_FAILED(rv)) continue;
#ifdef DEBUG_dp
printf("Populating dll: %s, %d, %d\n", library, lastModTime, fileSize);
#endif
}
return NS_OK;
}
@@ -624,9 +666,9 @@ nsNativeComponentLoader::AutoRegisterComponent(PRInt32 when,
nsStringKey key(persistentDescriptor);
// Check if dll is one that we have already seen
// Get the registry representation of the dll, if any
nsDll *dll;
rv = CreateDll(component, persistentDescriptor, &dll);
rv = CreateDll(component, persistentDescriptor, 0, 0, &dll);
if (NS_FAILED(rv))
return rv;
@@ -737,53 +779,6 @@ nsNativeComponentLoader::AutoRegisterComponent(PRInt32 when,
return ret;
}
#if 0
nsDll*
nsNativeComponentLoader::CreateCachedDll(const char *location,
PRUint32 modificationDate,
PRUint32 fileSize)
{
// Check our dllCollection for a dll with matching name
nsStringKey key(location);
nsDll *dll = (nsDll *) mDllStore->Get(&key);
if (dll == NULL)
{
PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS,
("nsNativeComponentLoader: New dll \"%s\".", location));
// Add a new Dll into the nsDllStore
dll = new nsDll(location, modificationDate, fileSize);
if (dll == NULL) return NULL;
if (dll->GetStatus() != DLL_OK) {
// Cant create a nsDll. Backoff.
PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS,
("nsNativeComponentLoader: ERROR in creating nsDll from \"%s\".",
location));
delete dll;
dll = NULL;
} else {
PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS,
("nsNativeComponentLoader: Adding New dll \"%s\" to mDllStore.",
location));
mDllStore->Put(&key, (void *)dll);
}
}
else
{
PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS,
("nsComponentManager: Found in mDllStore \"%s\".", location));
// XXX We found the dll in the dllCollection.
// XXX Consistency check: dll needs to have the same
// XXX lastModTime and fileSize. If not that would mean
// XXX that the dll wasn't registered properly.
}
return dll;
}
#endif
nsresult
nsNativeComponentLoader::OnRegister(const nsIID &aCID, const char *aType,
const char *aClassName,
@@ -802,9 +797,6 @@ nsNativeComponentLoader::UnloadAll(PRInt32 aWhen)
return NS_OK;
}
/*
* There are no interesting failures here, so we don't propagate errors back.
*/
nsresult
nsNativeComponentLoader::GetRegistryDllInfo(const char *aLocation,
PRUint32 *lastModifiedTime,
@@ -812,15 +804,20 @@ nsNativeComponentLoader::GetRegistryDllInfo(const char *aLocation,
{
nsresult rv;
*lastModifiedTime = 0;
*fileSize = 0;
nsIRegistry::Key key;
rv = mRegistry->GetSubtreeRaw(mXPCOMKey, aLocation, &key);
if (NS_FAILED(rv)) return rv;
return GetRegistryDllInfo(key, lastModifiedTime, fileSize);
}
nsresult
nsNativeComponentLoader::GetRegistryDllInfo(nsIRegistry::Key key,
PRUint32 *lastModifiedTime,
PRUint32 *fileSize)
{
int32 lastMod;
rv = mRegistry->GetInt(key, lastModValueName, &lastMod);
nsresult rv = mRegistry->GetInt(key, lastModValueName, &lastMod);
if (NS_FAILED(rv)) return rv;
*lastModifiedTime = lastMod;
@@ -847,12 +844,30 @@ nsNativeComponentLoader::SetRegistryDllInfo(const char *aLocation,
rv = mRegistry->SetInt(key, fileSizeValueName, fileSize);
return rv;
}
//
// CreateDll
// The only way to create a dll or get it from the dll cache. This will
// be called in multiple situations:
//
// 1. Autoregister will create one for each dll it is trying to register. This
// call will be passing a spec in.
// {spec, NULL, 0, 0}
//
// 2. GetFactory() This will call CreateDll() with a null spec but will give
// the registry represented name of the dll. If modtime and size are zero,
// we will go the registry to find the right modtime and size.
// {NULL, rel:libpref.so, 0, 0}
//
// 3. Prepopulation of dllCache A dll object created off a registry entry.
// Specifically dll name is stored in rel: or abs: or lib: formats in the
// registry along with its lastModTime and fileSize.
// {NULL, rel:libpref.so, 8985659, 20987}
nsresult
nsNativeComponentLoader::CreateDll(nsIFileSpec *aSpec,
const char *aLocation, nsDll **aDll)
nsNativeComponentLoader::CreateDll(nsIFileSpec *aSpec, const char *aLocation,
PRUint32 modificationTime, PRUint32 fileSize,
nsDll **aDll)
{
PRUint32 modificationTime = 0, fileSize = 0;
nsDll *dll;
nsFileSpec dllSpec;
nsCOMPtr<nsIFileSpec> spec;
@@ -885,12 +900,11 @@ nsNativeComponentLoader::CreateDll(nsIFileSpec *aSpec,
if (!dll)
{
rv = NS_OK;
if (mRegistry)
rv = GetRegistryDllInfo(aLocation, &modificationTime, &fileSize);
else
PR_LOG(nsComponentManagerLog, PR_LOG_ERROR,
("nsNativeComponentLoader: no registry, eep!"));
if (modificationTime == 0 && fileSize == 0)
{
// Get the modtime and filesize from the registry
rv = GetRegistryDllInfo(aLocation, &modificationTime, &fileSize);
}
dll = new nsDll(spec, aLocation, modificationTime, fileSize);
}

View File

@@ -51,11 +51,14 @@ class nsNativeComponentLoader : public nsIComponentLoader {
nsIRegistry::Key mXPCOMKey;
private:
nsresult CreateDll(nsIFileSpec *spec, const char *aLocation, nsDll **aDll);
nsresult CreateDll(nsIFileSpec *aSpec, const char *aLocation,
PRUint32 modifiedTime, PRUint32 fileSize, nsDll **aDll);
nsresult SelfRegisterDll(nsDll *dll, const char *registryLocation);
nsresult SelfUnregisterDll(nsDll *dll);
nsresult GetRegistryDllInfo(const char *aLocation, PRUint32 *lastModifiedTime,
PRUint32 *fileSize);
nsresult GetRegistryDllInfo(nsIRegistry::Key key, PRUint32 *lastModifiedTime,
PRUint32 *fileSize);
nsresult SetRegistryDllInfo(const char *aLocation, PRUint32 lastModifiedTime,
PRUint32 fileSize);
nsresult GetFactoryFromModule(nsDll *aDll, const nsCID &aCID,