Add experimental support to the native component loader so that native components can declare what libraries it depends on. (193442) Storing the GRE location in a relative way so that we can change GRE versions between launches assuming that they are compatible (191415). Fixed a bug where we didn't check return from GetLastModification in nsDll::HasChanged. Thank you ajschult@eos.ncsu.edu for pointing out the problem and suggesting a fix. Converted a linear search of compreg entries to be a hash lookup. Also cleaned up the xcdll class. Reviewers= Alec, Darin.

This commit is contained in:
dougt@netscape.com
2003-02-28 21:30:35 +00:00
parent cc4b20b575
commit 6f1eaa830d
16 changed files with 550 additions and 391 deletions

View File

@@ -76,7 +76,9 @@ nsNativeComponentLoader::~nsNativeComponentLoader()
delete mDllStore;
}
NS_IMPL_THREADSAFE_ISUPPORTS1(nsNativeComponentLoader, nsIComponentLoader);
NS_IMPL_THREADSAFE_ISUPPORTS2(nsNativeComponentLoader,
nsIComponentLoader,
nsINativeComponentLoader);
NS_IMETHODIMP
nsNativeComponentLoader::GetFactory(const nsIID & aCID,
@@ -128,13 +130,7 @@ nsNativeComponentLoader::GetFactory(const nsIID & aCID,
return rv; // XXX translate error code?
rv = GetFactoryFromModule(dll, aCID, _retval);
#ifdef OBSOLETE_MODULE_LOADING
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_FACTORY_NOT_LOADED) {
rv = GetFactoryFromNSGetFactory(dll, aCID, serviceMgr, _retval);
}
}
#endif
PR_LOG(nsComponentManagerLog, PR_LOG_ERROR,
("nsNativeComponentLoader: Factory creation %s for %s",
(NS_SUCCEEDED(rv) ? "succeeded" : "FAILED"),
@@ -276,25 +272,6 @@ nsFreeLibrary(nsDll *dll, nsIServiceManager *serviceMgr, PRInt32 when)
{
rv = mobj->CanUnload(nsComponentManagerImpl::gComponentManager, &canUnload);
}
#ifdef OBSOLETE_MODULE_LOADING
else
{
// Try the old method of module unloading
nsCanUnloadProc proc = (nsCanUnloadProc)dll->FindSymbol("NSCanUnload");
if (proc)
{
canUnload = proc(serviceMgr);
rv = NS_OK; // No error status returned by call.
}
else
{
PR_LOG(nsComponentManagerLog, PR_LOG_ERROR,
("nsNativeComponentLoader: Unload cant get nsIModule or NSCanUnload for %s",
dll->GetDisplayPath()));
return rv;
}
}
#endif /* OBSOLETE_MODULE_LOADING */
mobj = nsnull; // Release our reference to the module object
// When shutting down, whether we can unload the dll or not,
@@ -420,21 +397,6 @@ nsNativeComponentLoader::SelfRegisterDll(nsDll *dll,
}
mobj = NULL; // Force a release of the Module object before unload()
}
#ifdef OBSOLETE_MODULE_LOADING
else
{
res = NS_ERROR_NO_INTERFACE;
nsRegisterProc regproc = (nsRegisterProc)dll->FindSymbol("NSRegisterSelf");
if (regproc)
{
// Call the NSRegisterSelfProc to enable dll registration
res = regproc(serviceMgr, registryLocation);
PR_LOG(nsComponentManagerLog, PR_LOG_ERROR,
("nsNativeComponentLoader: %s using OBSOLETE NSRegisterSelf()",
dll->GetDisplayPath()));
}
}
#endif /* OBSOLETE_MODULE_LOADING */
// Update the timestamp and size of the dll in registry
// Don't enter deferred modules in the registry, because it might only be
@@ -579,19 +541,6 @@ nsNativeComponentLoader::SelfUnregisterDll(nsDll *dll)
if (NS_FAILED(res)) return res;
mobj->UnregisterSelf(mCompMgr, fs, registryName);
}
#ifdef OBSOLETE_MODULE_LOADING
else
{
res = NS_ERROR_NO_INTERFACE;
nsUnregisterProc unregproc =
(nsUnregisterProc) dll->FindSymbol("NSUnregisterSelf");
if (unregproc)
{
// Call the NSUnregisterSelfProc to enable dll de-registration
res = unregproc(serviceMgr, dll->GetPersistentDescriptorString());
}
}
#endif /* OBSOLETE_MODULE_LOADING */
return res;
}
@@ -863,7 +812,7 @@ nsNativeComponentLoader::AutoRegisterComponent(PRInt32 when,
// It is ok to do this even if the creation of nsDll
// didnt succeed. That way we wont do this again
// when we encounter the same dll.
dll = new nsDll(persistentDescriptor);
dll = new nsDll(component, persistentDescriptor);
if (dll == NULL)
return NS_ERROR_OUT_OF_MEMORY;
mDllStore->Put(&key, (void *) dll);
@@ -999,19 +948,14 @@ nsNativeComponentLoader::CreateDll(nsIFile *aSpec,
if (!aSpec)
{
if (!nsCRT::strncmp(aLocation, XPCOM_LIB_PREFIX, 4)) {
dll = new nsDll(aLocation+4, 1 /* dumb magic flag */);
if (!dll) return NS_ERROR_OUT_OF_MEMORY;
} else {
// what I want to do here is QI for a Component Registration Manager. Since this
// has not been invented yet, QI to the obsolete manager. Kids, don't do this at home.
nsCOMPtr<nsIComponentManagerObsolete> obsoleteManager = do_QueryInterface(mCompMgr, &rv);
if (obsoleteManager)
rv = obsoleteManager->SpecForRegistryLocation(aLocation,
getter_AddRefs(spec));
if (NS_FAILED(rv))
return rv;
}
// what I want to do here is QI for a Component Registration Manager. Since this
// has not been invented yet, QI to the obsolete manager. Kids, don't do this at home.
nsCOMPtr<nsIComponentManagerObsolete> obsoleteManager = do_QueryInterface(mCompMgr, &rv);
if (obsoleteManager)
rv = obsoleteManager->SpecForRegistryLocation(aLocation,
getter_AddRefs(spec));
if (NS_FAILED(rv))
return rv;
}
else
{
@@ -1046,11 +990,35 @@ nsNativeComponentLoader::GetFactoryFromModule(nsDll *aDll, const nsCID &aCID,
(void **)aFactory);
}
nsresult
nsNativeComponentLoader::GetFactoryFromNSGetFactory(nsDll *aDll,
const nsCID &aCID,
nsIServiceManager *aServMgr,
nsIFactory **aFactory)
NS_IMETHODIMP
nsNativeComponentLoader::AddDependentLibrary(nsIFile* aFile, const char* libName)
{
return NS_ERROR_FACTORY_NOT_LOADED;
nsCOMPtr<nsIComponentLoaderManager> manager = do_QueryInterface(mCompMgr);
if (!manager)
{
NS_WARNING("Something is terribly wrong");
return NS_ERROR_FAILURE;
}
// the native component loader uses the optional data
// to store a space delimited list of dependent library
// names
if (!libName)
{
manager->SetOptionalData(aFile, nsnull, nsnull);
return NS_OK;
}
nsXPIDLCString data;
manager->GetOptionalData(aFile, nsnull, getter_Copies(data));
if (!data.IsEmpty())
data.Append(NS_LITERAL_CSTRING(" "));
data.Append(nsDependentCString(libName));
manager->SetOptionalData(aFile, nsnull, data);
return NS_OK;
}