- NS_ERROR_FACTORY_REGISTER_AGAIN for deferring registration of a module until

later in the autoreg cycle.
- teach native component loader about deferred components
- add nsIComponentLoader::registerDeferredComponents
- teach component manager about deferred components
- made nsID::Parse take a |const char *| instead of a simple |char *|.
- move release of XPTI singletons until _after_ shutting down the component
  manager to prevent re-initialization during JS component shutdown.
- category manager work: really delete from reg, start on enumeration
- use nsXPIDLCString instead of autoStringFree.
- fix nsRegistry to use allocator properly.
- cleaner memory management in nsFactoryEntry.
- capitalization fixed in nsIComponentLoader.idl
- clean up loader creation logic
- remove/disable lots of DEBUG_shaver noise
- added (disabled) warning about NSGetFactory usage
- move .so and .shlb higher up in the ValidDllExtensions list to marginally
  speed up registration.
- added nsDll::GetRegistryLocation API
- properly export nsSupportsArray.h
- capitalization fixes in nsIEnumerator.idl
- added deferral to nsSample.js


git-svn-id: svn://10.0.0.236/trunk@53047 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
shaver%netscape.com
1999-11-10 00:28:34 +00:00
parent 51054c8b7a
commit 6896473ece
21 changed files with 266 additions and 255 deletions

View File

@@ -28,6 +28,7 @@
#include "xcDll.h"
#include "nsHashtable.h"
#include "nsHashtableEnumerator.h"
#include "nsXPIDLString.h"
#define PRINT_CRITICAL_ERROR_TO_SCREEN 1
#define USE_REGISTRY 1
@@ -35,33 +36,6 @@
extern PRLogModuleInfo *nsComponentManagerLog;
/* XXX consolidate with one in nsComponentManager.cpp */
//
// To prevent leaks, we are using this class. Typical use would be
// for each ptr to be deleted, create an object of these types with that ptr.
// Once that object goes out of scope, deletion and hence memory free will
// automatically happen.
//
class autoStringFree
{
public:
enum DeleteModel {
NSPR_Delete = 1,
nsCRT_String_Delete = 2
};
autoStringFree(char *Ptr, DeleteModel whichDelete): mPtr(Ptr), mWhichDelete(whichDelete) {}
~autoStringFree() {
if (mPtr)
if (mWhichDelete == NSPR_Delete) { PR_FREEIF(mPtr); }
else if (mWhichDelete == nsCRT_String_Delete) nsCRT::free(mPtr);
else PR_ASSERT(0);
}
private:
char *mPtr;
DeleteModel mWhichDelete;
};
nsNativeComponentLoader::nsNativeComponentLoader() :
mRegistry(nsnull), mCompMgr(nsnull), mDllStore(nsnull)
{
@@ -140,6 +114,14 @@ nsNativeComponentLoader::GetFactory(const nsIID & aCID,
if (NS_FAILED(rv)) {
if (rv == NS_ERROR_FACTORY_NOT_LOADED) {
rv = GetFactoryFromNSGetFactory(dll, aCID, serviceMgr, _retval);
#ifdef WARN_ABOUT_NSGETFACTORY
if (NS_SUCCEEDED(rv)) {
fprintf(stderr,
"XPCOM: Component %s uses DEPRECATED\n"
" NSGetFactory interface. This could break "
"AT ANY TIME.\n", dll->GetNativePath());
}
#endif
}
}
#endif
@@ -166,10 +148,6 @@ nsNativeComponentLoader::Init(nsIComponentManager *aCompMgr, nsISupports *aReg)
{
nsresult rv;
#ifdef DEBUG_shaver
fprintf(stderr, "nNCL: Init()\n");
#endif
mCompMgr = aCompMgr;
mRegistry = do_QueryInterface(aReg);
if (!mCompMgr || !mRegistry)
@@ -177,23 +155,15 @@ nsNativeComponentLoader::Init(nsIComponentManager *aCompMgr, nsISupports *aReg)
rv = mRegistry->GetSubtree(nsIRegistry::Common, xpcomKeyName,
&mXPCOMKey);
if (NS_FAILED(rv)) {
#ifdef DEBUG_shaver
fprintf(stderr, "nsNCL::Init: registry is hosed\n");
#endif
if (NS_FAILED(rv))
return rv;
}
if (!mDllStore) {
mDllStore = new nsObjectHashtable(nsnull, nsnull, // never copy
nsDll_Destroy, nsnull,
256, /* Thead Safe */ PR_TRUE);
if (!mDllStore) {
#ifdef DEBUG_shaver
fprintf(stderr, "nNCL::Init: couldn't build hash table\n");
#endif
if (!mDllStore)
return NS_ERROR_OUT_OF_MEMORY;
}
}
@@ -216,10 +186,9 @@ nsNativeComponentLoader::Init(nsIComponentManager *aCompMgr, nsISupports *aReg)
if (NS_FAILED(rv)) continue;
// Get library name
char *library = NULL;
rv = node->GetName(&library);
nsXPIDLCString library;
rv = node->GetName(getter_Copies(library));
if (NS_FAILED(rv)) continue;
autoStringFree delete_library(library, autoStringFree::nsCRT_String_Delete);
// Get key associated with library
nsRegistryKey libKey;
@@ -441,10 +410,12 @@ nsFreeLibraryEnum(nsHashKey *aKey, void *aData, void* closure)
*
*/
nsresult
nsNativeComponentLoader::SelfRegisterDll(nsDll *dll, const char *registryLocation)
nsNativeComponentLoader::SelfRegisterDll(nsDll *dll,
const char *registryLocation,
PRBool deferred)
{
// Precondition: dll is not loaded already
PR_ASSERT(dll->IsLoaded() == PR_FALSE);
// Precondition: dll is not loaded already, unless we're deferred
PR_ASSERT(deferred || dll->IsLoaded() == PR_FALSE);
nsIServiceManager* serviceMgr = NULL;
nsresult res = nsServiceManager::GetGlobalServiceManager(&serviceMgr);
@@ -505,8 +476,14 @@ nsNativeComponentLoader::SelfRegisterDll(nsDll *dll, const char *registryLocatio
#endif /* OBSOLETE_MODULE_LOADING */
// Update the timestamp and size of the dll in registry
dll->Sync();
SetRegistryDllInfo(registryLocation, dll->GetLastModifiedTime(), dll->GetSize());
// Don't enter deferred modules in the registry, because it might only be
// able to register on some later autoreg, after another component has been
// installed.
if (res != NS_ERROR_FACTORY_REGISTER_AGAIN) {
dll->Sync();
SetRegistryDllInfo(registryLocation, dll->GetLastModifiedTime(),
dll->GetSize());
}
return res;
}
@@ -573,7 +550,7 @@ nsNativeComponentLoader::DumpLoadError(nsDll *dll,
#endif // MOZ_DEMANGLE_SYMBOLS
// Do NSPR log
PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS,
PR_LOG(nsComponentManagerLog, PR_LOG_ERROR,
("nsNativeComponentLoader: %s(%s) Load FAILED with error:%s",
aCallerName,
dll->GetNativePath(),
@@ -656,12 +633,12 @@ nsNativeComponentLoader::AutoRegisterComponent(PRInt32 when,
/* this should be a pref or registry entry, or something */
const char *ValidDllExtensions[] = {
".dll", /* Windows */
".so", /* Unix */
".shlb", /* Mac ? */
".dso", /* Unix ? */
".dylib", /* Unix: Rhapsody */
".so", /* Unix */
".so.1.0", /* Unix: BSD */
".sl", /* Unix: HP-UX */
".shlb", /* Mac ? */
#if defined(VMS)
".exe", /* Open VMS */
#endif
@@ -731,21 +708,12 @@ nsNativeComponentLoader::AutoRegisterComponent(PRInt32 when,
// Skip invalid extensions
return NS_OK;
/*
* Get the name of the dll
* I think I get to go through every type of string here.
* Pink would be so proud.
*/
char *persistentDescriptor;
rv = mCompMgr->RegistryLocationForSpec(component, &persistentDescriptor);
nsXPIDLCString persistentDescriptor;
rv = mCompMgr->RegistryLocationForSpec(component,
getter_Copies(persistentDescriptor));
if (NS_FAILED(rv))
return rv;
autoStringFree
delete_persistentDescriptor(persistentDescriptor,
autoStringFree::nsCRT_String_Delete);
nsStringKey key(persistentDescriptor);
// Get the registry representation of the dll, if any
@@ -834,19 +802,19 @@ nsNativeComponentLoader::AutoRegisterComponent(PRInt32 when,
// changed since we last saw it and it is unloaded successfully.
//
// Now we can try register the dll for sure.
nsresult res = SelfRegisterDll(dll, persistentDescriptor);
nsresult ret = NS_OK;
nsresult res = SelfRegisterDll(dll, persistentDescriptor, PR_FALSE);
if (NS_FAILED(res))
{
PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS,
("nsNativeComponentLoader: Autoregistration FAILED for "
"\"%s\". Skipping...", dll->GetNativePath()));
// Mark dll as not xpcom dll along with modified time and size in
// the registry so that we wont need to load the dll again every
// session until the dll changes.
#ifdef USE_REGISTRY
#endif /* USE_REGISTRY */
ret = NS_ERROR_FAILURE;
if (res == NS_ERROR_FACTORY_REGISTER_AGAIN) {
/* defer for later loading */
mDeferredComponents.AppendElement(dll);
return NS_OK;
} else {
PR_LOG(nsComponentManagerLog, PR_LOG_ERROR,
("nsNativeComponentLoader: Autoregistration FAILED for "
"\"%s\". Skipping...", dll->GetNativePath()));
return NS_ERROR_FACTORY_NOT_REGISTERED;
}
}
else
{
@@ -857,7 +825,39 @@ nsNativeComponentLoader::AutoRegisterComponent(PRInt32 when,
// registry happens at PlatformRegister(). No need to do it
// here again.
}
return ret;
return NS_OK;
}
nsresult
nsNativeComponentLoader::RegisterDeferredComponents(PRInt32 aWhen,
PRBool *aRegistered)
{
fprintf(stderr, "nNCL: registering deferred (%d)\n",
mDeferredComponents.Count());
*aRegistered = PR_FALSE;
if (!mDeferredComponents.Count())
return NS_OK;
for (int i = mDeferredComponents.Count() - 1; i >= 0; i--) {
nsDll *dll = NS_STATIC_CAST(nsDll *, mDeferredComponents[i]);
nsresult rv = SelfRegisterDll(dll,
dll->GetRegistryLocation(),
PR_TRUE);
if (rv != NS_ERROR_FACTORY_REGISTER_AGAIN) {
if (NS_SUCCEEDED(rv))
*aRegistered = PR_TRUE;
mDeferredComponents.RemoveElementAt(i);
}
}
if (*aRegistered)
fprintf(stderr, "nNCL: registered deferred, %d left\n",
mDeferredComponents.Count());
else
fprintf(stderr, "nNCL: didn't register any components, %d left\n",
mDeferredComponents.Count());
/* are there any fatal errors? */
return NS_OK;
}
nsresult