1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3 * ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is the Mozilla browser.
18 * The Initial Developer of the Original Code is
19 * Netscape Communications, Inc.
20 * Portions created by the Initial Developer are Copyright (C) 1999
21 * the Initial Developer. All Rights Reserved.
25 * Alternatively, the contents of this file may be used under the terms of
26 * either the GNU General Public License Version 2 or later (the "GPL"), or
27 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 #include "nsIServiceManager.h"
40 #include "nsIComponentManager.h"
41 #include "nsIComponentRegistrar.h"
42 #include "nsIAppStartupNotifier.h"
43 #include "nsIStringBundle.h"
45 #include "nsIDirectoryService.h"
46 #include "nsDirectoryServiceDefs.h"
49 #include "nsEmbedAPI.h"
51 static nsIServiceManager
*sServiceManager
= nsnull
;
52 static PRBool sRegistryInitializedFlag
= PR_FALSE
;
53 static PRUint32 sInitCounter
= 0;
55 #define HACK_AROUND_THREADING_ISSUES
56 //#define HACK_AROUND_NONREENTRANT_INITXPCOM
58 #ifdef HACK_AROUND_NONREENTRANT_INITXPCOM
59 // XXX hack class to clean up XPCOM when this module is unloaded
60 class XPCOMCleanupHack
65 XPCOMCleanupHack() : mCleanOnExit(PR_FALSE
) {}
75 // XXX Global destructors and NS_ShutdownXPCOM don't seem to mix
76 // NS_ShutdownXPCOM(sServiceManager);
80 static PRBool sXPCOMInitializedFlag
= PR_FALSE
;
81 static XPCOMCleanupHack sXPCOMCleanupHack
;
86 NS_InitEmbedding(nsILocalFile
*mozBinDirectory
,
87 nsIDirectoryServiceProvider
*appFileLocProvider
,
88 nsStaticModuleInfo
const *aStaticComponents
,
89 PRUint32 aStaticComponentCount
)
93 // Reentrant calls to this method do nothing except increment a counter
99 #ifdef HACK_AROUND_NONREENTRANT_INITXPCOM
100 // Can't call NS_InitXPCom more than once or things go boom!
101 if (!sXPCOMInitializedFlag
)
105 rv
= NS_InitXPCOM3(&sServiceManager
, mozBinDirectory
, appFileLocProvider
,
106 aStaticComponents
, aStaticComponentCount
);
107 NS_ENSURE_SUCCESS(rv
, rv
);
109 #ifdef HACK_AROUND_NONREENTRANT_INITXPCOM
110 sXPCOMInitializedFlag
= PR_TRUE
;
111 sXPCOMCleanupHack
.mCleanOnExit
= PR_TRUE
;
114 // Register components
115 if (!sRegistryInitializedFlag
)
118 nsIComponentRegistrar
*registrar
;
119 rv
= sServiceManager
->QueryInterface(NS_GET_IID(nsIComponentRegistrar
),
120 (void **) ®istrar
);
123 NS_WARNING("Could not QI to registrar");
126 rv
= registrar
->AutoRegister(nsnull
);
129 NS_WARNING("Could not AutoRegister");
133 // If the application is using an GRE, then, auto register components
134 // in the GRE directory as well.
136 // The application indicates that it's using an GRE by returning a
137 // valid nsIFile when queried (via appFileLocProvider) for the
138 // NS_GRE_DIR atom as shown below
140 if (appFileLocProvider
)
142 nsIFile
*greDir
= nsnull
;
143 PRBool persistent
= PR_TRUE
;
145 appFileLocProvider
->GetFile(NS_GRE_DIR
, &persistent
,
149 rv
= registrar
->AutoRegister(greDir
);
151 NS_WARNING("Could not AutoRegister GRE components");
156 NS_RELEASE(registrar
);
160 sRegistryInitializedFlag
= PR_TRUE
;
163 nsIComponentManager
*compMgr
;
164 rv
= sServiceManager
->QueryInterface(NS_GET_IID(nsIComponentManager
),
169 nsIObserver
*startupNotifier
;
170 rv
= compMgr
->CreateInstanceByContractID(NS_APPSTARTUPNOTIFIER_CONTRACTID
,
172 NS_GET_IID(nsIObserver
),
173 (void **) &startupNotifier
);
178 startupNotifier
->Observe(nsnull
, APPSTARTUP_TOPIC
, nsnull
);
179 NS_RELEASE(startupNotifier
);
181 #ifdef HACK_AROUND_THREADING_ISSUES
182 // XXX force certain objects to be created on the main thread
183 nsIStringBundleService
*bundleService
;
184 rv
= sServiceManager
->GetServiceByContractID(NS_STRINGBUNDLE_CONTRACTID
,
185 NS_GET_IID(nsIStringBundleService
),
186 (void **) &bundleService
);
187 if (NS_SUCCEEDED(rv
))
189 nsIStringBundle
*stringBundle
;
190 const char propertyURL
[] = "chrome://necko/locale/necko.properties";
191 rv
= bundleService
->CreateBundle(propertyURL
, &stringBundle
);
192 NS_RELEASE(stringBundle
);
193 NS_RELEASE(bundleService
);
203 // Reentrant calls to this method do nothing except decrement a counter
204 if (sInitCounter
> 1)
211 NS_IF_RELEASE(sServiceManager
);
213 // Terminate XPCOM & cleanup
214 #ifndef HACK_AROUND_NONREENTRANT_INITXPCOM
215 nsresult rv
= NS_ShutdownXPCOM(sServiceManager
);
216 NS_ENSURE_SUCCESS(rv
, rv
);