Mozilla/mozilla/embedding/base/nsEmbedAPI.cpp
dougt%netscape.com ecdd8ab65f Fixes the following:
154047
This change cleans up the category manager in hopes to freeze it for 1.1 final.  This change removes dead and unsupported methods from the interface as well as removes the C++ code from the interface.  This should land for 1.1b since users of the current category manager will have to update their components.

157597
Make embedding base and examples use XPCOM Glue
This change makes our embedding samples use the XPCOM glue.

157625
nsLocalFile::Remove's file pointer is sometimes null afte...
This fixes a crash when we dereference null.  It is a bandaide fix as the real problems involves retooling the directory enumerator.

157801
This fixes a terrible state which you can get into whereby XPCOM will fail to startup regardless of what you do.  The fix is to cause autoreg to happen if the component registry (compreg.dat) is not found.

r/sr=alecf@netscape.com, rpotts@netscape.com.  a=scc@mozilla.org


git-svn-id: svn://10.0.0.236/trunk@125444 18797224-902f-48f8-a5cc-f745e15eee43
2002-07-18 05:09:10 +00:00

193 lines
5.4 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is the Mozilla browser.
*
* The Initial Developer of the Original Code is Netscape
* Communications, Inc. Portions created by Netscape are
* Copyright (C) 1999, Mozilla. All Rights Reserved.
*
* Author:
* Adam Lock <adamlock@netscape.com>
*
* Contributor(s):
*/
#ifdef XPCOM_GLUE
#include "nsXPCOMGlue.h"
#endif
#include "nsIServiceManager.h"
#include "nsIComponentRegistrar.h"
#include "nsIAppStartupNotifier.h"
#include "nsIStringBundle.h"
#include "nsIDirectoryService.h"
#include "nsDirectoryServiceDefs.h"
#include "nsEmbedAPI.h"
#include "nsLiteralString.h"
static nsIServiceManager *sServiceManager = nsnull;
static PRBool sRegistryInitializedFlag = PR_FALSE;
static PRUint32 sInitCounter = 0;
#define HACK_AROUND_THREADING_ISSUES
//#define HACK_AROUND_NONREENTRANT_INITXPCOM
#ifdef HACK_AROUND_NONREENTRANT_INITXPCOM
// XXX hack class to clean up XPCOM when this module is unloaded
class XPCOMCleanupHack
{
public:
PRBool mCleanOnExit;
XPCOMCleanupHack() : mCleanOnExit(PR_FALSE) {}
~XPCOMCleanupHack()
{
if (mCleanOnExit)
{
if (sInitCounter > 0)
{
sInitCounter = 1;
NS_TermEmbedding();
}
// XXX Global destructors and NS_ShutdownXPCOM don't seem to mix
// NS_ShutdownXPCOM(sServiceManager);
}
}
};
static PRBool sXPCOMInitializedFlag = PR_FALSE;
static XPCOMCleanupHack sXPCOMCleanupHack;
#endif
nsresult NS_InitEmbedding(nsILocalFile *mozBinDirectory,
nsIDirectoryServiceProvider *appFileLocProvider)
{
nsresult rv;
// Reentrant calls to this method do nothing except increment a counter
sInitCounter++;
if (sInitCounter > 1)
return NS_OK;
// Initialise XPCOM
#ifdef HACK_AROUND_NONREENTRANT_INITXPCOM
// Can't call NS_InitXPCom more than once or things go boom!
if (!sXPCOMInitializedFlag)
#endif
{
#ifdef XPCOM_GLUE
// TODO: Need to be smarter about where exactly the xpcom library is.
XPCOMGlueStartup(nsnull);
#endif
// Initialise XPCOM
NS_InitXPCOM2(&sServiceManager, mozBinDirectory, appFileLocProvider);
#ifdef HACK_AROUND_NONREENTRANT_INITXPCOM
sXPCOMInitializedFlag = PR_TRUE;
sXPCOMCleanupHack.mCleanOnExit = PR_TRUE;
#endif
}
// Register components
if (!sRegistryInitializedFlag)
{
nsCOMPtr<nsIComponentRegistrar> registrar = do_QueryInterface(sServiceManager, &rv);
if (NS_FAILED(rv))
{
NS_ASSERTION(PR_FALSE, "Could not QI to registrar");
return rv;
}
rv = registrar->AutoRegister(nsnull);
if (NS_FAILED(rv))
{
NS_ASSERTION(PR_FALSE, "Could not AutoRegister");
return rv;
}
// If the application is using an MRE, then,
// auto register components in the MRE directory as well.
//
// The application indicates that it's using an MRE by
// returning a valid nsIFile when queried (via appFileLocProvider)
// for the NS_MRE_DIR atom as shown below
//
if (appFileLocProvider)
{
nsCOMPtr<nsIFile> mreDir;
PRBool persistent = PR_TRUE;
appFileLocProvider->GetFile(NS_MRE_DIR, &persistent, getter_AddRefs(mreDir));
if (mreDir)
{
rv = registrar->AutoRegister(mreDir);
if (NS_FAILED(rv))
{
NS_ASSERTION(PR_FALSE, "Could not AutoRegister MRE components");
return rv;
}
}
}
sRegistryInitializedFlag = PR_TRUE;
}
nsCOMPtr<nsIObserver> mStartupNotifier = do_CreateInstance(NS_APPSTARTUPNOTIFIER_CONTRACTID, &rv);
if(NS_FAILED(rv))
return rv;
mStartupNotifier->Observe(nsnull, APPSTARTUP_TOPIC, nsnull);
#ifdef HACK_AROUND_THREADING_ISSUES
// XXX force certain objects to be created on the main thread
nsCOMPtr<nsIStringBundleService> sBundleService;
sBundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv))
{
nsCOMPtr<nsIStringBundle> stringBundle;
const char propertyURL[] = "chrome://necko/locale/necko.properties";
rv = sBundleService->CreateBundle(propertyURL,
getter_AddRefs(stringBundle));
}
#endif
return NS_OK;
}
nsresult NS_TermEmbedding()
{
// Reentrant calls to this method do nothing except decrement a counter
if (sInitCounter > 1)
{
sInitCounter--;
return NS_OK;
}
sInitCounter = 0;
NS_IF_RELEASE(sServiceManager);
// Terminate XPCOM & cleanup
#ifndef HACK_AROUND_NONREENTRANT_INITXPCOM
NS_ShutdownXPCOM(sServiceManager);
#endif
#ifdef XPCOM_GLUE
XPCOMGlueShutdown();
#endif
return NS_OK;
}