- Fixing ComponentManager destruction

- CLSIDToProdID() fixed to use the correct subtree in registry
- ProgID() enumneration on startup enabled
- Added internal UnloadLibraries() that can take a NULL service
  manager too for nsXPComShutdown()'s sake
- Setting autoreg DirectoryIterator not to resolve symbolic links


git-svn-id: svn://10.0.0.236/trunk@41681 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
dp%netscape.com
1999-07-31 05:55:04 +00:00
parent 3d8399c70a
commit 174729ddab

View File

@@ -104,7 +104,7 @@ nsFactoryEntry::~nsFactoryEntry(void)
}
////////////////////////////////////////////////////////////////////////////////
// autoFree
// autoStringFree
////////////////////////////////////////////////////////////////////////////////
//
@@ -215,18 +215,35 @@ nsresult nsComponentManagerImpl::Init(void)
nsComponentManagerImpl::~nsComponentManagerImpl()
{
PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS, ("nsComponentManager: Beginning destruction."));
// Release all cached factories
if (mFactories)
delete mFactories;
// Unload libraries
UnloadLibraries(NULL);
// Release Progid hash tables
if (mProgIDs)
delete mProgIDs;
if (mMon)
PR_DestroyMonitor(mMon);
// Release dll abstraction storage
if (mDllStore)
delete mDllStore;
#ifdef USE_REGISTRY
// Release registry
if(mRegistry)
NS_RELEASE(mRegistry);
#endif /* USE_REGISTRY */
// Destroy the Lock
if (mMon)
PR_DestroyMonitor(mMon);
PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS, ("nsComponentManager: Destroyed."));
}
NS_IMPL_ISUPPORTS(nsComponentManagerImpl, nsIComponentManager::GetIID());
@@ -694,7 +711,7 @@ nsComponentManagerImpl::PlatformCLSIDToProgID(nsCID *aClass,
char* cidStr = aClass->ToString();
nsIRegistry::Key cidKey;
rv = mRegistry->GetSubtreeRaw(mClassesKey,cidStr,&cidKey);
rv = mRegistry->GetSubtreeRaw(mCLSIDKey, cidStr, &cidKey);
if(NS_FAILED(rv)) return rv;
PR_FREEIF(cidStr);
@@ -781,7 +798,6 @@ nsresult nsComponentManagerImpl::PlatformPrePopulateRegistry()
char *cidString = NULL;
rv = node->GetName(&cidString);
if (NS_FAILED(rv)) continue;
// XXX make sure the following will work
autoStringFree delete_cidString(cidString, autoStringFree::nsCRT_String_Delete);
// Get key associated with library
@@ -793,7 +809,6 @@ nsresult nsComponentManagerImpl::PlatformPrePopulateRegistry()
char *library = NULL;
rv = mRegistry->GetString(cidKey, inprocServerValueName, &library);
if (NS_FAILED(rv)) continue;
// XXX wont work in this scope
autoStringFree delete_library(library, autoStringFree::NSPR_Delete);
nsCID aClass;
if (!(aClass.Parse(cidString))) continue;
@@ -805,14 +820,53 @@ nsresult nsComponentManagerImpl::PlatformPrePopulateRegistry()
nsIDKey key(aClass);
mFactories->Put(&key, entry);
// printf("Populating cid: %s, %s\n", cidString, library);
}
// Finally read in PROGID -> CID mappings
// Naa. Only about 20 progid are always got. So prepopulating this
// doesn't make much sense now. If this gets higher, more close to
// the number of progid that exist, this would make sense.
nsCOMPtr<nsIEnumerator> progidEnum;
rv = mRegistry->EnumerateSubtrees( mClassesKey, getter_AddRefs(progidEnum));
if (NS_FAILED(rv)) return rv;
rv = progidEnum->First();
for (; NS_SUCCEEDED(rv) && !progidEnum->IsDone(); (rv = progidEnum->Next()))
{
nsCOMPtr<nsISupports> base;
rv = progidEnum->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 the progid string
char *progidString = NULL;
rv = node->GetName(&progidString);
if (NS_FAILED(rv)) continue;
autoStringFree delete_progidString(progidString, autoStringFree::nsCRT_String_Delete);
// Get cid string
nsIRegistry::Key progidKey;
rv = node->GetKey(&progidKey);
if (NS_FAILED(rv)) continue;
char *cidString = NULL;
rv = mRegistry->GetString(progidKey, classIDValueName, &cidString);
if (NS_FAILED(rv)) continue;
autoStringFree delete_cidString(cidString, autoStringFree::NSPR_Delete);
nsCID *aClass = new nsCID();
if (!aClass) continue; // Protect against out of memory.
if (!(aClass->Parse(cidString)))
{
delete aClass;
continue;
}
// put the {progid, Cid} mapping into our map
nsStringKey key(progidString);
mProgIDs->Put(&key, aClass);
// printf("Populating [ %s, %s ]\n", cidString, progidString);
}
return NS_OK;
}
@@ -1669,20 +1723,27 @@ nsComponentManagerImpl::UnregisterComponent(const nsCID &aClass,
static PRBool
nsFreeLibraryEnum(nsHashKey *aKey, void *aData, void* closure)
{
nsFactoryEntry *entry = (nsFactoryEntry *) aData;
nsDll *dll = (nsDll *) aData;
nsIServiceManager* serviceMgr = (nsIServiceManager*)closure;
if (entry->dll && entry->dll->IsLoaded() == PR_TRUE)
if (dll && dll->IsLoaded() == PR_TRUE)
{
nsCanUnloadProc proc = (nsCanUnloadProc) entry->dll->FindSymbol("NSCanUnload");
nsCanUnloadProc proc = (nsCanUnloadProc) dll->FindSymbol("NSCanUnload");
if (proc != NULL) {
nsresult rv = proc(serviceMgr);
if (NS_FAILED(rv))
PRBool canUnload = proc(serviceMgr);
if (canUnload == PR_TRUE)
{
PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS,
("nsComponentManager: + Unloading \"%s\".", entry->dll->GetNativePath()));
entry->dll->Unload();
("nsComponentManager: + Unloading \"%s\".", dll->GetNativePath()));
#if 0
// XXX dlls aren't counting their outstanding instances correctly
// XXX hence, dont unload until this gets enforced.
dll->Unload();
#endif /* 0 */
}
else
PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS,
("nsComponentManager: + NOT Unloading \"%s\".", dll->GetNativePath()));
}
}
@@ -1692,18 +1753,26 @@ nsFreeLibraryEnum(nsHashKey *aKey, void *aData, void* closure)
nsresult
nsComponentManagerImpl::FreeLibraries(void)
{
PR_EnterMonitor(mMon);
PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS,
("nsComponentManager: Freeing Libraries."));
nsIServiceManager* serviceMgr = NULL;
nsresult rv = nsServiceManager::GetGlobalServiceManager(&serviceMgr);
if (NS_FAILED(rv)) return rv;
mFactories->Enumerate(nsFreeLibraryEnum, serviceMgr);
rv = UnloadLibraries(serviceMgr);
return rv;
}
// Private implementation of unloading libraries
nsresult
nsComponentManagerImpl::UnloadLibraries(nsIServiceManager *serviceMgr)
{
PR_EnterMonitor(mMon);
PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS,
("nsComponentManager: Unloading Libraries."));
mDllStore->Enumerate(nsFreeLibraryEnum, serviceMgr);
PR_ExitMonitor(mMon);
return NS_OK;
}
@@ -1788,7 +1857,7 @@ nsComponentManagerImpl::SyncComponentsInDir(RegistrationTime when, nsIFileSpec *
nsCOMPtr<nsIDirectoryIterator>dirIterator;
rv = CreateInstance(NS_DIRECTORYITERATOR_PROGID, NULL, kDirectoryIteratorIID, getter_AddRefs(dirIterator));
if (NS_FAILED(rv)) return rv;
rv = dirIterator->Init(dirSpec, PR_TRUE);
rv = dirIterator->Init(dirSpec, PR_FALSE);
if (NS_FAILED(rv)) return rv;
// whip through the directory to register every file