Implemented component unregistration.

This commit is contained in:
dp%netscape.com 2000-04-18 05:25:05 +00:00
Родитель eef0576e74
Коммит 10d2c3b870
8 изменённых файлов: 116 добавлений и 51 удалений

Просмотреть файл

@ -1770,56 +1770,35 @@ nsresult
nsComponentManagerImpl::UnregisterComponentSpec(const nsCID &aClass,
nsIFile *aLibrarySpec)
{
char *aLibrary;
nsresult rv = aLibrarySpec->GetPath(&aLibrary);
if (NS_FAILED(rv))
return NS_ERROR_INVALID_ARG;
if (PR_LOG_TEST(nsComponentManagerLog, PR_LOG_ALWAYS))
{
char *buf = aClass.ToString();
PR_LogPrint("nsComponentManager: UnregisterComponentSpec(%s, %s)", buf,
aLibrary);
delete [] buf;
}
nsIDKey key(aClass);
nsFactoryEntry *old = (nsFactoryEntry *) mFactories->Get(&key);
nsresult res = NS_ERROR_FACTORY_NOT_REGISTERED;
nsXPIDLCString registryName;
nsresult rv = RegistryLocationForSpec(aLibrarySpec, getter_Copies(registryName));
if (NS_FAILED(rv)) return NS_ERROR_INVALID_ARG;
PR_EnterMonitor(mMon);
if (old != NULL)
// Remove any stored factory entries
nsIDKey key(aClass);
nsFactoryEntry *entry = (nsFactoryEntry *) mFactories->Get(&key);
if (entry && entry->location && PL_strcasecmp(entry->location, registryName))
{
#if 0 /* use nsFactoryEntry->location */
if (old->dll->GetPersistentDescriptorString() != NULL &&
#if defined(XP_UNIX) || defined(XP_BEOS)
PL_strcasecmp(old->dll->GetPersistentDescriptorString(), aLibrary)
#else
PL_strcmp(old->dll->GetPersistentDescriptorString(), aLibrary)
#endif
)
{
mFactories->RemoveAndDelete(&key);
old = NULL;
res = NS_OK;
}
#ifdef USE_REGISTRY
char *cidString = aClass.ToString();
res = PlatformUnregister(cidString, aLibrary);
delete [] cidString;
#endif
#endif
mFactories->RemoveAndDelete(&key);
entry = NULL;
}
#ifdef USE_REGISTRY
// Remove registry entries for this cid
char *cidString = aClass.ToString();
rv = PlatformUnregister(cidString, registryName);
delete [] cidString;
#endif
PR_ExitMonitor(mMon);
PR_LOG(nsComponentManagerLog, PR_LOG_WARNING,
("nsComponentManager: ! Factory unregister %s.",
NS_SUCCEEDED(res) ? "succeeded" : "failed"));
("nsComponentManager: Factory unregister(%s) %s.", (const char *)registryName,
NS_SUCCEEDED(rv) ? "succeeded" : "FAILED"));
return res;
return rv;
}
struct CanUnload_closure {
@ -2037,10 +2016,25 @@ AutoRegisterComponent_enumerate(nsHashKey *key, void *aData, void *aClosure)
&didRegister);
if (NS_SUCCEEDED(closure->status) && didRegister)
return PR_FALSE;
if (didRegister)
return PR_TRUE;
return PR_FALSE;
return PR_FALSE; // Stop enumeration as we are done
return PR_TRUE;
}
static PRBool
AutoUnregisterComponent_enumerate(nsHashKey *key, void *aData, void *aClosure)
{
PRBool didUnregister;
nsIComponentLoader *loader = (nsIComponentLoader *)aData;
struct AutoReg_closure *closure =
(struct AutoReg_closure *)aClosure;
closure->status = loader->AutoUnregisterComponent(closure->when,
closure->spec,
&didUnregister);
if (NS_SUCCEEDED(closure->status) && didUnregister)
return PR_FALSE; // Stop enumeration as we are done
return PR_TRUE; // Let enumeration continue
}
nsresult
@ -2064,6 +2058,24 @@ nsComponentManagerImpl::AutoRegisterComponent(PRInt32 when,
}
nsresult
nsComponentManagerImpl::AutoUnregisterComponent(PRInt32 when,
nsIFile *component)
{
struct AutoReg_closure closure;
/* XXX convert when to nsIComponentLoader::(when) properly */
closure.when = (PRInt32)when;
closure.spec = component;
closure.status = NS_OK;
mLoaders->Enumerate(AutoUnregisterComponent_enumerate, &closure);
return NS_FAILED(closure.status)
? NS_ERROR_FACTORY_NOT_REGISTERED : NS_OK;
}
nsresult
nsComponentManagerImpl::IsRegistered(const nsCID &aClass,
PRBool *aRegistered)

Просмотреть файл

@ -161,6 +161,7 @@ public:
// in the default components directory.
static nsresult AutoRegister(PRInt32 when, nsIFile* directory);
static nsresult AutoRegisterComponent(PRInt32 when, nsIFile *component);
static nsresult AutoUnregisterComponent(PRInt32 when, nsIFile *component);
// Is the given CID currently registered?
static nsresult IsRegistered(const nsCID &aClass,

Просмотреть файл

@ -1,4 +1,4 @@
/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.1 (the "NPL"); you may not use this file except in
@ -68,6 +68,13 @@ interface nsIComponentLoader : nsISupports {
*/
boolean autoRegisterComponent(in long aWhen, in nsIFile aComponent);
/**
* AutoUnregister the given component.
* Returns true if the component was unregistered, false if it coudln't
* attempt to unregister the component (not found, wrong type).
*/
boolean autoUnregisterComponent(in long aWhen, in nsIFile aComponent);
/**
* Register any deferred (NS_ERROR_FACTORY_REGISTER_AGAIN) components.
* Return registered-any-components?

Просмотреть файл

@ -86,6 +86,7 @@ interface nsIComponentManager : nsISupports
void autoRegister(in long when, in nsIFile directory);
void autoRegisterComponent(in long when, in nsIFile component);
void autoUnregisterComponent(in long when, in nsIFile component);
boolean isRegistered(in nsCIDRef aClass);
nsIEnumerator enumerateCLSIDs();

Просмотреть файл

@ -579,9 +579,6 @@ nsNativeComponentLoader::DumpLoadError(nsDll *dll,
nsresult
nsNativeComponentLoader::SelfUnregisterDll(nsDll *dll)
{
// Precondition: dll is not loaded
PR_ASSERT(dll->IsLoaded() == PR_FALSE);
nsIServiceManager* serviceMgr = NULL;
nsresult res = nsServiceManager::GetGlobalServiceManager(&serviceMgr);
if (NS_FAILED(res)) return res;
@ -623,10 +620,39 @@ nsNativeComponentLoader::SelfUnregisterDll(nsDll *dll)
}
}
#endif /* OBSOLETE_MODULE_LOADING */
dll->Unload();
return res;
}
nsresult
nsNativeComponentLoader::AutoUnregisterComponent(PRInt32 when,
nsIFile *component,
PRBool *unregistered)
{
nsresult rv = NS_ERROR_FAILURE;
nsXPIDLCString persistentDescriptor;
rv = mCompMgr->RegistryLocationForSpec(component,
getter_Copies(persistentDescriptor));
if (NS_FAILED(rv)) return rv;
nsDll *dll = NULL;
PRInt64 mod = LL_Zero(), size = LL_Zero();
rv = CreateDll(component, persistentDescriptor, &mod, &size, &dll);
if (NS_FAILED(rv) || dll == NULL) return rv;
rv = SelfUnregisterDll(dll);
// Remove any autoreg info about this dll
if (NS_SUCCEEDED(rv))
RemoveRegistryDllInfo(persistentDescriptor);
PR_LOG(nsComponentManagerLog, PR_LOG_ERROR,
("nsNativeComponentLoader: AutoUnregistration for %s %s.",
(NS_FAILED(rv) ? "FAILED" : "succeeded"), dll->GetDisplayPath()));
return rv;
}
nsresult
nsNativeComponentLoader::AutoRegisterComponent(PRInt32 when,
nsIFile *component,
@ -940,6 +966,12 @@ nsNativeComponentLoader::SetRegistryDllInfo(const char *aLocation,
return rv;
}
nsresult
nsNativeComponentLoader::RemoveRegistryDllInfo(const char *aLocation)
{
return mRegistry->RemoveSubtree(mXPCOMKey, aLocation);
}
//
// CreateDll
// The only way to create a dll or get it from the dll cache. This will

Просмотреть файл

@ -64,6 +64,7 @@ class nsNativeComponentLoader : public nsIComponentLoader {
PRInt64 *fileSize);
nsresult SetRegistryDllInfo(const char *aLocation, PRInt64 *lastModifiedTime,
PRInt64 *fileSize);
nsresult RemoveRegistryDllInfo(const char *aLocation);
nsresult GetFactoryFromModule(nsDll *aDll, const nsCID &aCID,
nsIFactory **aFactory);
/* obsolete! already! */

Просмотреть файл

@ -210,6 +210,16 @@ nsComponentManager::AutoRegisterComponent(PRInt32 when,
return cm->AutoRegisterComponent(when, fullname);
}
nsresult
nsComponentManager::AutoUnregisterComponent(PRInt32 when,
nsIFile *fullname)
{
nsIComponentManager* cm;
nsresult rv = NS_GetGlobalComponentManager(&cm);
if (NS_FAILED(rv)) return rv;
return cm->AutoUnregisterComponent(when, fullname);
}
nsresult
nsComponentManager::IsRegistered(const nsCID &aClass,
PRBool *aRegistered)

Просмотреть файл

@ -161,6 +161,7 @@ public:
// in the default components directory.
static nsresult AutoRegister(PRInt32 when, nsIFile* directory);
static nsresult AutoRegisterComponent(PRInt32 when, nsIFile *component);
static nsresult AutoUnregisterComponent(PRInt32 when, nsIFile *component);
// Is the given CID currently registered?
static nsresult IsRegistered(const nsCID &aClass,