From e75485644c5e0d70b9672a7053f0b4f83b231315 Mon Sep 17 00:00:00 2001 From: "dougt%netscape.com" Date: Tue, 16 Oct 2001 03:35:52 +0000 Subject: [PATCH] API Freeze for nsIServiceManager r=shaver@mozilla.org, sr=rpotts@netscape.com bug 99147 --- build/mac/build_scripts/MozillaBuildList.pm | 1 + chrome/tools/chromereg/regchrome.cpp | 2 +- config/bin2rc.exe | Bin 16384 -> 16384 bytes config/makecopy.exe | Bin 16384 -> 16384 bytes config/makedep.exe | Bin 110592 -> 110592 bytes config/mangle.exe | Bin 16384 -> 16384 bytes config/mantomak.exe | Bin 20480 -> 20480 bytes extensions/cookie/tests/TestCookie.cpp | 2 +- extensions/python/xpcom/src/xpcom.cpp | 8 +- extensions/xmlextras/tests/TestXMLExtras.cpp | 2 +- .../xpconnect/loader/mozJSComponentLoader.cpp | 8 +- js/src/xpconnect/shell/xpcshell.cpp | 2 +- layout/html/forms/src/nsFormFrame.cpp | 1 + modules/libjar/test/TestJarCache.cpp | 2 +- modules/plugin/base/src/ns4xPlugin.cpp | 13 +- modules/plugin/base/src/ns4xPlugin.h | 6 +- modules/plugin/base/src/nsPluginHostImpl.cpp | 4 +- modules/plugin/base/src/nsPluginsDirUnix.cpp | 4 +- netwerk/test/TestCacheBlockFiles.cpp | 2 +- netwerk/test/TestCacheService.cpp | 2 +- netwerk/test/TestCallbacks.cpp | 2 +- netwerk/test/TestProtocols.cpp | 2 +- netwerk/test/TestThreadedIO.cpp | 2 +- .../Acct/nsAccount.cpp | 0 rdf/chrome/tools/chromereg/regchrome.cpp | 2 +- webshell/tests/viewer/nsBeOSMain.cpp | 2 +- webshell/tests/viewer/nsMacMain.cpp | 2 +- webshell/tests/viewer/nsPhMain.cpp | 2 +- webshell/tests/viewer/nsWinMain.cpp | 2 +- webshell/tests/viewer/unix/gtk/nsGtkMain.cpp | 2 +- xpcom/base/nsLeakDetector.cpp | 8 +- xpcom/build/MANIFEST | 1 + xpcom/build/Makefile.in | 4 + xpcom/build/makefile.win | 4 + xpcom/build/nsXPCOM.h | 113 +++ xpcom/build/nsXPComInit.cpp | 30 +- xpcom/components/MANIFEST | 3 +- xpcom/components/MANIFEST_IDL | 1 + xpcom/components/Makefile.in | 7 +- xpcom/components/makefile.win | 7 +- xpcom/components/nsCategoryManager.cpp | 66 ++ xpcom/components/nsComponentManager.cpp | 655 +++++------------- xpcom/components/nsComponentManager.h | 46 +- xpcom/components/nsICategoryManager.idl | 5 + xpcom/components/nsIServiceManager.idl | 107 +++ xpcom/components/nsIServiceManagerObsolete.h | 289 ++++++++ xpcom/components/nsIServiceManagerUtils.h | 187 +++++ xpcom/components/nsNativeComponentLoader.cpp | 27 +- xpcom/components/nsServiceManagerObsolete.cpp | 179 +++++ xpcom/glue/nsServiceManagerUtils.h | 187 +++++ xpcom/sample/nsTestSample.cpp | 2 +- xpcom/tests/TestBuffers.cpp | 2 +- xpcom/tests/TestPipes.cpp | 2 +- xpcom/tests/TestShutdown.cpp | 2 +- xpcom/tests/TestThreads.cpp | 2 +- xpcom/tests/nsIFileEnumerator.cpp | 2 +- xpcom/tests/windows/TestHelloXPLoop.cpp | 2 +- xpcom/tools/registry/regExport.cpp | 3 +- xpcom/tools/registry/regxpcom.cpp | 2 +- xpfe/bootstrap/nsAppRunner.cpp | 2 +- xpinstall/stub/xpistub.cpp | 8 +- 61 files changed, 1434 insertions(+), 598 deletions(-) rename xpcom/components/nsIServiceManager.h => profile/Acct/nsAccount.cpp (100%) create mode 100644 xpcom/build/MANIFEST create mode 100644 xpcom/build/nsXPCOM.h create mode 100644 xpcom/components/nsIServiceManager.idl create mode 100644 xpcom/components/nsIServiceManagerObsolete.h create mode 100644 xpcom/components/nsIServiceManagerUtils.h create mode 100644 xpcom/components/nsServiceManagerObsolete.cpp create mode 100644 xpcom/glue/nsServiceManagerUtils.h diff --git a/build/mac/build_scripts/MozillaBuildList.pm b/build/mac/build_scripts/MozillaBuildList.pm index e3a62ef8549..15483db97d1 100644 --- a/build/mac/build_scripts/MozillaBuildList.pm +++ b/build/mac/build_scripts/MozillaBuildList.pm @@ -571,6 +571,7 @@ sub BuildClientDist() InstallFromManifest(":mozilla:xpcom:threads:MANIFEST_IDL", "$distdirectory:idl:"); InstallFromManifest(":mozilla:xpcom:components:MANIFEST_IDL", "$distdirectory:idl:"); + InstallFromManifest(":mozilla:xpcom:build:MANIFEST", "$distdirectory:xpcom:"); InstallFromManifest(":mozilla:xpcom:glue:MANIFEST", "$distdirectory:xpcom:"); InstallFromManifest(":mozilla:xpcom:base:MANIFEST", "$distdirectory:xpcom:"); InstallFromManifest(":mozilla:xpcom:components:MANIFEST", "$distdirectory:xpcom:"); diff --git a/chrome/tools/chromereg/regchrome.cpp b/chrome/tools/chromereg/regchrome.cpp index 3dc502292e0..954b2985c6a 100644 --- a/chrome/tools/chromereg/regchrome.cpp +++ b/chrome/tools/chromereg/regchrome.cpp @@ -25,7 +25,7 @@ int main(int argc, char **argv) { - NS_InitXPCOM(nsnull, nsnull); + NS_InitXPCOM2(nsnull, nsnull, nsnull); nsCOMPtr chromeReg = do_GetService("@mozilla.org/chrome/chrome-registry;1"); diff --git a/config/bin2rc.exe b/config/bin2rc.exe index c553ac5b8a25f1fd10808b543eac758906f26738..1b2d0d56e097cded892204c618537ce24a03730f 100755 GIT binary patch delta 16 XcmZo@U~Fh$oN$BrF!Rohw^i){I9mqY delta 16 YcmZo@U~Fh$oN$AA;`LP!n^06VG&Z~y=R diff --git a/config/makecopy.exe b/config/makecopy.exe index 7347d043bae607d37e2285b1380d28ed1ac274bc..9d31ba07b8c3439e3c2bd8d2f4eb78d8093746f6 100755 GIT binary patch delta 16 XcmZo@U~Fh$obZ785cAHBk7exvIHU&T delta 16 YcmZo@U~Fh$obZ5o!u3@fAIsVU06X&scK`qY diff --git a/config/makedep.exe b/config/makedep.exe index 7586eee0edf3a5a3e8fd6f7b9a54238a2350b4af..2fc3f92a891fb900dd1e76688d99eca4a3fc2cdd 100755 GIT binary patch delta 19 bcmZp8z}E19ZNdxYBg{J+UvGWQD7qd1U?T~c delta 19 bcmZp8z}E19ZNdxYN!M33zTWzpQFJ{3Wh)9S diff --git a/config/mangle.exe b/config/mangle.exe index 5394e759be5df533f73eb7f4a39113e032e79fc8..8a991778843a2c406852ea8fbb82da4e38800940 100755 GIT binary patch delta 16 XcmZo@U~Fh$obZ78F!Rohk7exvII9Nb delta 16 YcmZo@U~Fh$obZ5o!u3@fAIsVU06X&scK`qY diff --git a/config/mantomak.exe b/config/mantomak.exe index 95a677a0a030a184f7951f39a01190f219e6592f..968824be7edb43b3d5c9f6ebaaae49fe0f22059e 100755 GIT binary patch delta 16 YcmZozz}T>Wal#Ge!^}H3-d6Po06WVEEdT%j delta 16 YcmZozz}T>Wal#GeiPu+cyshdF06!WBzyJUM diff --git a/extensions/cookie/tests/TestCookie.cpp b/extensions/cookie/tests/TestCookie.cpp index f6186b0bb11..4475d6a66c2 100644 --- a/extensions/cookie/tests/TestCookie.cpp +++ b/extensions/cookie/tests/TestCookie.cpp @@ -89,7 +89,7 @@ void GetACookie(nsICookieService *cookieService, const char* aSpec, char* *aCook int main(PRInt32 argc, char *argv[]) { - nsresult rv = NS_InitXPCOM(nsnull, nsnull); + nsresult rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); if (NS_FAILED(rv)) return -1; // Create the Event Queue for this thread... diff --git a/extensions/python/xpcom/src/xpcom.cpp b/extensions/python/xpcom/src/xpcom.cpp index b5e6782f501..2c66ba1c7ae 100644 --- a/extensions/python/xpcom/src/xpcom.cpp +++ b/extensions/python/xpcom/src/xpcom.cpp @@ -179,10 +179,10 @@ PyXPCOMMethod_GetGlobalServiceManager(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; - nsIServiceManager* sm; + nsIServiceManagerObsolete* sm; nsresult rv; Py_BEGIN_ALLOW_THREADS; - rv = nsServiceManager::GetGlobalServiceManager(&sm); + rv = nsServiceManager::GetGlobalServiceManager((nsIServiceManager**)&sm); Py_END_ALLOW_THREADS; if ( NS_FAILED(rv) ) return PyXPCOM_BuildPyException(rv); @@ -509,10 +509,10 @@ PRBool PyXPCOM_Globals_Ensure() nsCOMPtr ns_bin_dir; NS_NewLocalFile(landmark, PR_FALSE, getter_AddRefs(ns_bin_dir)); - nsresult rv = NS_InitXPCOM(nsnull, ns_bin_dir); + nsresult rv = NS_InitXPCOM2(nsnull, ns_bin_dir, nsnull); #else // Elsewhere, Mozilla can find it itself (we hope!) - nsresult rv = NS_InitXPCOM(nsnull, nsnull); + nsresult rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); #endif // XP_WIN if (NS_FAILED(rv)) { PyErr_SetString(PyExc_RuntimeError, "The XPCOM subsystem could not be initialized"); diff --git a/extensions/xmlextras/tests/TestXMLExtras.cpp b/extensions/xmlextras/tests/TestXMLExtras.cpp index 959eb46fcd8..3859869d512 100644 --- a/extensions/xmlextras/tests/TestXMLExtras.cpp +++ b/extensions/xmlextras/tests/TestXMLExtras.cpp @@ -126,7 +126,7 @@ int main (int argc, char* argv[]) nsIServiceManager *servMgr; - rv = NS_InitXPCOM(&servMgr, nsnull); + rv = NS_InitXPCOM2(&servMgr, nsnull, nsnull); if (NS_FAILED(rv)) return rv; if (argc > 2) { diff --git a/js/src/xpconnect/loader/mozJSComponentLoader.cpp b/js/src/xpconnect/loader/mozJSComponentLoader.cpp index 566e0f81ebb..75305c97dd1 100644 --- a/js/src/xpconnect/loader/mozJSComponentLoader.cpp +++ b/js/src/xpconnect/loader/mozJSComponentLoader.cpp @@ -835,8 +835,8 @@ mozJSComponentLoader::AttemptRegistration(nsIFile *component, do_GetService(kObserverServiceContractID); if (observerService) { - nsIServiceManager *mgr; // NO COMPtr as we dont release the service manager - rv = nsServiceManager::GetGlobalServiceManager(&mgr); + nsCOMPtr mgr; + rv = NS_GetServiceManager(getter_AddRefs(mgr)); if (NS_SUCCEEDED(rv)) { // this string can't come from a string bundle, because we don't have string @@ -900,8 +900,8 @@ mozJSComponentLoader::UnregisterComponent(nsIFile *component) do_GetService(kObserverServiceContractID); if (observerService) { - nsIServiceManager *mgr; // NO COMPtr as we dont release the service manager - rv = nsServiceManager::GetGlobalServiceManager(&mgr); + nsCOMPtr mgr; + rv = NS_GetServiceManager(getter_AddRefs(mgr)); if (NS_SUCCEEDED(rv)) { (void) observerService->Notify(mgr, diff --git a/js/src/xpconnect/shell/xpcshell.cpp b/js/src/xpconnect/shell/xpcshell.cpp index 48092062605..fbeaccd8cc9 100644 --- a/js/src/xpconnect/shell/xpcshell.cpp +++ b/js/src/xpconnect/shell/xpcshell.cpp @@ -834,7 +834,7 @@ main(int argc, char **argv) gErrFile = stderr; gOutFile = stdout; - rv = NS_InitXPCOM(NULL, NULL); + rv = NS_InitXPCOM2(NULL, NULL, NULL); if (NS_FAILED(rv)) { printf("NS_InitXPCOM failed!\n"); return 1; diff --git a/layout/html/forms/src/nsFormFrame.cpp b/layout/html/forms/src/nsFormFrame.cpp index e8f25906702..3f827926a15 100644 --- a/layout/html/forms/src/nsFormFrame.cpp +++ b/layout/html/forms/src/nsFormFrame.cpp @@ -100,6 +100,7 @@ static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); #include "nsIFormSubmitObserver.h" #include "nsIObserverService.h" #include "nsIServiceManager.h" +#include "nsICategoryManager.h" // Get base target for submission #include "nsIHTMLContent.h" diff --git a/modules/libjar/test/TestJarCache.cpp b/modules/libjar/test/TestJarCache.cpp index 81d05439d40..d4f03349f19 100644 --- a/modules/libjar/test/TestJarCache.cpp +++ b/modules/libjar/test/TestJarCache.cpp @@ -163,7 +163,7 @@ int main(int argc, char **argv) } filenames = argv + 1; - rv = NS_InitXPCOM(nsnull, nsnull); + rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); if(NS_FAILED(rv)) { printf("NS_InitXPCOM failed!\n"); diff --git a/modules/plugin/base/src/ns4xPlugin.cpp b/modules/plugin/base/src/ns4xPlugin.cpp index d3030acc16f..b9aa69f1c44 100644 --- a/modules/plugin/base/src/ns4xPlugin.cpp +++ b/modules/plugin/base/src/ns4xPlugin.cpp @@ -43,6 +43,7 @@ #include "ns4xPluginInstance.h" #include "ns4xPluginStreamListener.h" #include "nsIServiceManager.h" + #include "nsIMemory.h" #include "nsIPluginStreamListener.h" #include "nsPluginsDir.h" @@ -79,7 +80,7 @@ static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID); //////////////////////////////////////////////////////////////////////// // Globals NPNetscapeFuncs ns4xPlugin::CALLBACKS; -static nsIServiceManager* gServiceMgr = nsnull; +static nsIServiceManagerObsolete* gServiceMgr = nsnull; static nsIMemory* gMalloc = nsnull; //////////////////////////////////////////////////////////////////////// @@ -127,7 +128,7 @@ ns4xPlugin::CheckClassInitialized(void) // nsISupports stuff NS_IMPL_ISUPPORTS2(ns4xPlugin, nsIPlugin, nsIFactory); -ns4xPlugin::ns4xPlugin(NPPluginFuncs* callbacks, PRLibrary* aLibrary, NP_PLUGINSHUTDOWN aShutdown, nsIServiceManager* serviceMgr) +ns4xPlugin::ns4xPlugin(NPPluginFuncs* callbacks, PRLibrary* aLibrary, NP_PLUGINSHUTDOWN aShutdown, nsIServiceManagerObsolete* serviceMgr) { NS_INIT_REFCNT(); memset((void*) &fCallbacks, 0, sizeof(fCallbacks)); @@ -225,7 +226,7 @@ void ns4xPlugin::SetPluginRefNum(short aRefNum) //One ns4xPlugin object exists per Plugin (not instance). nsresult -ns4xPlugin::CreatePlugin(nsIServiceManager* aServiceMgr, +ns4xPlugin::CreatePlugin(nsIServiceManagerObsolete* aServiceMgr, const char* aFileName, PRLibrary* aLibrary, nsIPlugin** aResult) @@ -1119,10 +1120,10 @@ _getvalue(NPP npp, NPNVariable variable, void *result) case NPNVserviceManager: { // GetGlobalServiceManager does not AddRef, so we do here. - nsIServiceManager* serviceManager; - res = nsServiceManager::GetGlobalServiceManager(&serviceManager); + nsIServiceManagerObsolete* serviceManager; + res = nsServiceManager::GetGlobalServiceManager((nsIServiceManager**)&serviceManager); if (NS_SUCCEEDED(res)) { - *(nsIServiceManager**)result = serviceManager; + *(nsIServiceManagerObsolete**)result = serviceManager; NS_ADDREF(serviceManager); return NPERR_NO_ERROR; } else diff --git a/modules/plugin/base/src/ns4xPlugin.h b/modules/plugin/base/src/ns4xPlugin.h index 2ca716b0f91..e91d99d686e 100644 --- a/modules/plugin/base/src/ns4xPlugin.h +++ b/modules/plugin/base/src/ns4xPlugin.h @@ -74,7 +74,7 @@ typedef NS_CALLBACK_(NPError, NP_PLUGINSHUTDOWN) (void); typedef NS_CALLBACK_(NPError, NP_MAIN) (NPNetscapeFuncs* nCallbacks, NPPluginFuncs* pCallbacks, NPP_ShutdownUPP* unloadUpp); #endif -class nsIServiceManager; +class nsIServiceManagerObsolete; class nsIMemory; //////////////////////////////////////////////////////////////////////// @@ -87,7 +87,7 @@ class ns4xPlugin : public nsIPlugin { public: - ns4xPlugin(NPPluginFuncs* callbacks, PRLibrary* aLibrary, NP_PLUGINSHUTDOWN aShutdown, nsIServiceManager* serviceMgr); + ns4xPlugin(NPPluginFuncs* callbacks, PRLibrary* aLibrary, NP_PLUGINSHUTDOWN aShutdown, nsIServiceManagerObsolete* serviceMgr); virtual ~ns4xPlugin(void); static void ReleaseStatics(); @@ -135,7 +135,7 @@ public: */ static nsresult - CreatePlugin(nsIServiceManager* aServiceMgr, + CreatePlugin(nsIServiceManagerObsolete* aServiceMgr, const char* aFileName, PRLibrary* aLibrary, nsIPlugin** aResult); diff --git a/modules/plugin/base/src/nsPluginHostImpl.cpp b/modules/plugin/base/src/nsPluginHostImpl.cpp index d083165997e..5fbc7de9990 100644 --- a/modules/plugin/base/src/nsPluginHostImpl.cpp +++ b/modules/plugin/base/src/nsPluginHostImpl.cpp @@ -4206,8 +4206,8 @@ NS_IMETHODIMP nsPluginHostImpl::GetPluginFactory(const char *aMimeType, nsIPlugi { // No, this is not a leak. GetGlobalServiceManager() doesn't // addref the pointer on the way out. It probably should. - nsIServiceManager* serviceManager; - nsServiceManager::GetGlobalServiceManager(&serviceManager); + nsIServiceManagerObsolete* serviceManager; + nsServiceManager::GetGlobalServiceManager((nsIServiceManager**)&serviceManager); // need to get the plugin factory from this plugin. nsFactoryProc nsGetFactory = nsnull; diff --git a/modules/plugin/base/src/nsPluginsDirUnix.cpp b/modules/plugin/base/src/nsPluginsDirUnix.cpp index e3b8d15aaa8..d30486438fa 100644 --- a/modules/plugin/base/src/nsPluginsDirUnix.cpp +++ b/modules/plugin/base/src/nsPluginsDirUnix.cpp @@ -420,8 +420,8 @@ nsresult nsPluginFile::GetPluginInfo(nsPluginInfo& info) // No, this doesn't leak. GetGlobalServiceManager() doesn't addref // it's out pointer. Maybe it should. - nsIServiceManager* mgr; - nsServiceManager::GetGlobalServiceManager(&mgr); + nsIServiceManagerObsolete* mgr; + nsServiceManager::GetGlobalServiceManager((nsIServiceManager**)&mgr); nsFactoryProc nsGetFactory = (nsFactoryProc) PR_FindSymbol(pLibrary, "NSGetFactory"); diff --git a/netwerk/test/TestCacheBlockFiles.cpp b/netwerk/test/TestCacheBlockFiles.cpp index 4a6e035d894..03ca5ade990 100644 --- a/netwerk/test/TestCacheBlockFiles.cpp +++ b/netwerk/test/TestCacheBlockFiles.cpp @@ -212,7 +212,7 @@ main(void) nsresult rv = NS_OK; // Start up XPCOM - rv = NS_InitXPCOM(nsnull, nsnull); + rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); if (NS_FAILED(rv)) return rv; // Register components diff --git a/netwerk/test/TestCacheService.cpp b/netwerk/test/TestCacheService.cpp index b5b661c1185..4856b0ae6aa 100644 --- a/netwerk/test/TestCacheService.cpp +++ b/netwerk/test/TestCacheService.cpp @@ -183,7 +183,7 @@ main(int argc, char* argv[]) nsresult rv = NS_OK; // Start up XPCOM - rv = NS_InitXPCOM(nsnull, nsnull); + rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); if (NS_FAILED(rv)) return rv; /** diff --git a/netwerk/test/TestCallbacks.cpp b/netwerk/test/TestCallbacks.cpp index 296f3355e20..542a9308466 100644 --- a/netwerk/test/TestCallbacks.cpp +++ b/netwerk/test/TestCallbacks.cpp @@ -249,7 +249,7 @@ int main(int argc, char *argv[]) { cmdLineURL = PR_TRUE; } - rv = NS_InitXPCOM(nsnull, nsnull); + rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); if (NS_FAILED(rv)) return rv; // Create the Event Queue for this thread... diff --git a/netwerk/test/TestProtocols.cpp b/netwerk/test/TestProtocols.cpp index ffbd93a02a3..c9ff5bd1023 100644 --- a/netwerk/test/TestProtocols.cpp +++ b/netwerk/test/TestProtocols.cpp @@ -537,7 +537,7 @@ main(int argc, char* argv[]) up the event queues. Copied from TestSocketIO.cpp */ - rv = NS_InitXPCOM(nsnull, nsnull); + rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); if (NS_FAILED(rv)) return rv; diff --git a/netwerk/test/TestThreadedIO.cpp b/netwerk/test/TestThreadedIO.cpp index e2f84fbf8e6..d7102f9d964 100644 --- a/netwerk/test/TestThreadedIO.cpp +++ b/netwerk/test/TestThreadedIO.cpp @@ -269,7 +269,7 @@ main( int argc, char* argv[] ) { // Initialize XPCOM. printf( "Initializing XPCOM...\n" ); - rv = NS_InitXPCOM( 0, 0 ); + rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); if ( NS_SUCCEEDED( rv ) ) { printf( "...XPCOM initialized OK\n" ); diff --git a/xpcom/components/nsIServiceManager.h b/profile/Acct/nsAccount.cpp similarity index 100% rename from xpcom/components/nsIServiceManager.h rename to profile/Acct/nsAccount.cpp diff --git a/rdf/chrome/tools/chromereg/regchrome.cpp b/rdf/chrome/tools/chromereg/regchrome.cpp index 3dc502292e0..954b2985c6a 100644 --- a/rdf/chrome/tools/chromereg/regchrome.cpp +++ b/rdf/chrome/tools/chromereg/regchrome.cpp @@ -25,7 +25,7 @@ int main(int argc, char **argv) { - NS_InitXPCOM(nsnull, nsnull); + NS_InitXPCOM2(nsnull, nsnull, nsnull); nsCOMPtr chromeReg = do_GetService("@mozilla.org/chrome/chrome-registry;1"); diff --git a/webshell/tests/viewer/nsBeOSMain.cpp b/webshell/tests/viewer/nsBeOSMain.cpp index b5b7f4ad262..ba8a76f13cf 100644 --- a/webshell/tests/viewer/nsBeOSMain.cpp +++ b/webshell/tests/viewer/nsBeOSMain.cpp @@ -178,7 +178,7 @@ int main(int argc, char **argv) return 1; // Init XPCOM - nsresult rv = NS_InitXPCOM(nsnull, nsnull); + nsresult rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); NS_ASSERTION(NS_SUCCEEDED(rv), "NS_InitXPCOM failed"); if (NS_SUCCEEDED(rv)) { diff --git a/webshell/tests/viewer/nsMacMain.cpp b/webshell/tests/viewer/nsMacMain.cpp index 68b3f6b348a..17dcbe81f1f 100644 --- a/webshell/tests/viewer/nsMacMain.cpp +++ b/webshell/tests/viewer/nsMacMain.cpp @@ -450,7 +450,7 @@ int main(int argc, char **argv) NS_ASSERTION((err==noErr), "AEInstallEventHandler failed"); // Start up XPCOM? - nsresult rv = NS_InitXPCOM(nsnull, nsnull); + nsresult rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); NS_ASSERTION(NS_SUCCEEDED(rv), "NS_InitXPCOM failed"); gTheApp = new nsNativeViewerApp(); diff --git a/webshell/tests/viewer/nsPhMain.cpp b/webshell/tests/viewer/nsPhMain.cpp index 0eaa651c724..a673e49fd50 100644 --- a/webshell/tests/viewer/nsPhMain.cpp +++ b/webshell/tests/viewer/nsPhMain.cpp @@ -185,7 +185,7 @@ int main(int argc, char **argv) signal(SIGABRT, abnormal_exit_handler); // Initialize XPCOM - nsresult rv = NS_InitXPCOM(nsnull, nsnull); + nsresult rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); NS_ASSERTION(NS_SUCCEEDED(rv), "NS_InitXPCOM failed"); if (NS_SUCCEEDED(rv)) { // The toolkit service in mozilla will look in the environment diff --git a/webshell/tests/viewer/nsWinMain.cpp b/webshell/tests/viewer/nsWinMain.cpp index 2fbff5ebb31..157e06ae3f3 100644 --- a/webshell/tests/viewer/nsWinMain.cpp +++ b/webshell/tests/viewer/nsWinMain.cpp @@ -164,7 +164,7 @@ nsNativeBrowserWindow::DispatchMenuItem(PRInt32 aID) int main(int argc, char **argv) { nsresult rv; - rv = NS_InitXPCOM(nsnull, nsnull); + rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); NS_ASSERTION(NS_SUCCEEDED(rv), "NS_InitXPCOM failed"); nsViewerApp* app = new nsNativeViewerApp(); NS_ADDREF(app); diff --git a/webshell/tests/viewer/unix/gtk/nsGtkMain.cpp b/webshell/tests/viewer/unix/gtk/nsGtkMain.cpp index d07aceafdf0..046ed0264ad 100644 --- a/webshell/tests/viewer/unix/gtk/nsGtkMain.cpp +++ b/webshell/tests/viewer/unix/gtk/nsGtkMain.cpp @@ -181,7 +181,7 @@ int main(int argc, char **argv) #endif // CRAWL_STACK_ON_SIGSEGV // Initialize XPCOM - nsresult rv = NS_InitXPCOM(nsnull, nsnull); + nsresult rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); NS_ASSERTION(NS_SUCCEEDED(rv), "NS_InitXPCOM failed"); if (NS_SUCCEEDED(rv)) { // The toolkit service in mozilla will look in the environment diff --git a/xpcom/base/nsLeakDetector.cpp b/xpcom/base/nsLeakDetector.cpp index 8489fe3b63a..2b42adbf45a 100644 --- a/xpcom/base/nsLeakDetector.cpp +++ b/xpcom/base/nsLeakDetector.cpp @@ -146,13 +146,7 @@ NS_METHOD nsLeakDetector::MarkObject(nsISupports* object, PRBool marked) NS_METHOD nsLeakDetector::GetServices(nsISupports* *result) { - nsIServiceManager* serviceManager = nsnull; - nsresult rv = nsServiceManager::GetGlobalServiceManager(&serviceManager); - if (rv == NS_OK) { - *result = serviceManager; - NS_ADDREF(*result); - } - return rv; + return NS_GetServiceManager(result); } #define NS_CLEAKDETECTOR_CID_STR "bb1ba360-1dd1-11b2-b30e-aa2314429f54" diff --git a/xpcom/build/MANIFEST b/xpcom/build/MANIFEST new file mode 100644 index 00000000000..7b9bf8ff830 --- /dev/null +++ b/xpcom/build/MANIFEST @@ -0,0 +1 @@ +nsXPCOM.h diff --git a/xpcom/build/Makefile.in b/xpcom/build/Makefile.in index f01a8f331b7..b9a85b9a39f 100644 --- a/xpcom/build/Makefile.in +++ b/xpcom/build/Makefile.in @@ -34,6 +34,10 @@ REQUIRES = libreg \ string \ $(NULL) +EXPORTS = \ + nsXPCOM.h \ + $(NULL) + CPPSRCS = nsXPComInit.cpp ifdef XPCOM_USE_LEA diff --git a/xpcom/build/makefile.win b/xpcom/build/makefile.win index 6e65d6982f4..73f878cb9e2 100644 --- a/xpcom/build/makefile.win +++ b/xpcom/build/makefile.win @@ -34,6 +34,10 @@ MAKE_OBJ_TYPE=DLL LIBNAME = .\$(OBJDIR)\xpcom DLL = $(LIBNAME).dll +EXPORTS = \ + nsXPCOM.h \ + $(NULL) + # if we ever add a .def file for x86 we need to deal with this. !if "$(CPU)" == "ALPHA" DEFFILE = xpcom_alpha.def diff --git a/xpcom/build/nsXPCOM.h b/xpcom/build/nsXPCOM.h new file mode 100644 index 00000000000..16f91b51f8b --- /dev/null +++ b/xpcom/build/nsXPCOM.h @@ -0,0 +1,113 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape 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/NPL/ + * + * 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 mozilla.org code. + * + * The Initial Developer of the Original Code is + * Netscape Communications Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsXPComInit_h__ +#define nsXPComInit_h__ + +#include "nscore.h" + +class nsIServiceManager; +class nsIFile; +class nsIDirectoryServiceProvider; + +/** + * Initialises XPCOM. You must call this method before proceeding + * to use xpcom. The one exception is that you may call + * NS_NewLocalFile to create a nsIFile. + * + * @status FROZEN + * + * @note Use NS_NewLocalFile to create the file object you + * supply as the bin directory path in this call. The function + * may be safely called before the rest of XPCOM or embedding has + * been initialised. + * + * @param result The service manager. You may pass null. + * + * @param abinDirectory The directory containing the component + * registry and runtime libraries; + * or use nsnull to use the working + * directory. + * + * @param aAppFileLocProvider The object to be used by Gecko that specifies + * to Gecko where to find profiles, the component + * registry preferences and so on; or use + * nsnull for the default behaviour. + * + * @see NS_NewLocalFile + * @see nsILocalFile + * @see nsIDirectoryServiceProvider + * + * @return NS_OK for success; + * other error codes indicate a failure during initialisation. + * + */ +extern "C" NS_COM nsresult +NS_InitXPCOM2(nsIServiceManager* *result, + nsIFile* binDirectory, + nsIDirectoryServiceProvider* appFileLocationProvider); +/** + * Shutdown XPCOM. You must call this method after you are finished + * using xpcom. + * + * @status FROZEN + * + * @param servMgr The service manager which was returned by NS_InitXPCOM2. + * This will release servMgr. You may pass null. + * + * @return NS_OK for success; + * other error codes indicate a failure during initialisation. + * + */ +extern "C" NS_COM nsresult +NS_ShutdownXPCOM(nsIServiceManager* servMgr); + + +/** + * Public Method to access to the service manager. + * + * @status FROZEN + * @param result Interface pointer to the service + * + * @return NS_OK for success; + * other error codes indicate a failure during initialisation. + * + */ +extern "C" NS_COM nsresult +NS_GetServiceManager(nsIServiceManager* *result); + +#endif diff --git a/xpcom/build/nsXPComInit.cpp b/xpcom/build/nsXPComInit.cpp index 46fb8e50054..137768bb63c 100644 --- a/xpcom/build/nsXPComInit.cpp +++ b/xpcom/build/nsXPComInit.cpp @@ -35,6 +35,7 @@ * * ***** END LICENSE BLOCK ***** */ +#include "nsXPCom.h" #include "nsIRegistry.h" #include "nscore.h" #include "nsCOMPtr.h" @@ -171,14 +172,13 @@ RegisterGenericFactory(nsIComponentManager* compMgr, } // Globals in xpcom - -nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = NULL; #ifndef XPCOM_STANDALONE nsICaseConversion *gCaseConv = NULL; #endif /* XPCOM_STANDALONE */ + +nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = NULL; nsIProperties *gDirectoryService = NULL; -extern nsIServiceManager* gServiceManager; -extern PRBool gShuttingDown; +PRBool gXPCOMShuttingDown = PR_FALSE; // For each class that wishes to support nsIClassInfo, add a line like this // NS_DECL_CLASSINFO(nsMyClass) @@ -353,19 +353,22 @@ nsresult NS_COM NS_InitXPCOM2(nsIServiceManager* *result, return rv; } - gServiceManager = NS_STATIC_CAST(nsIServiceManager*, compMgr); + nsIServiceManager *serviceManager = NS_STATIC_CAST(nsIServiceManager*, compMgr); nsComponentManagerImpl::gComponentManager = compMgr; if (result) { - NS_ADDREF(*result = gServiceManager); + NS_ADDREF(*result = serviceManager); } } + nsIServiceManager *serviceManager = NS_STATIC_CAST(nsIServiceManager*, compMgr); nsCOMPtr memory = getter_AddRefs(nsMemory::GetGlobalMemoryService()); - rv = gServiceManager->RegisterService(kMemoryCID, memory); + + // dougt - these calls will be moved into a new interface when nsIComponentManager is frozen. + rv = compMgr->RegisterService(kMemoryCID, memory); if (NS_FAILED(rv)) return rv; - rv = gServiceManager->RegisterService(kComponentManagerCID, NS_STATIC_CAST(nsIComponentManager*, compMgr)); + rv = compMgr->RegisterService(kComponentManagerCID, NS_STATIC_CAST(nsIComponentManager*, compMgr)); if (NS_FAILED(rv)) return rv; #ifdef GC_LEAK_DETECTOR @@ -455,8 +458,8 @@ nsresult NS_COM NS_ShutdownXPCOM(nsIServiceManager* servMgr) do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv); if (NS_SUCCEEDED(rv)) { - nsIServiceManager *mgr; // NO COMPtr as we dont release the service manager - rv = nsServiceManager::GetGlobalServiceManager(&mgr); + nsCOMPtr mgr; + rv = NS_GetServiceManager(getter_AddRefs(mgr)); if (NS_SUCCEEDED(rv)) { nsAutoString topic; @@ -479,15 +482,16 @@ nsresult NS_COM NS_ShutdownXPCOM(nsIServiceManager* servMgr) // XPCOM is officially in shutdown mode NOW // Set this only after the observers have been notified as this // will cause servicemanager to become inaccessible. - gShuttingDown = PR_TRUE; + gXPCOMShuttingDown = PR_TRUE; // We may have AddRef'd for the caller of NS_InitXPCOM, so release it // here again: NS_IF_RELEASE(servMgr); // Shutdown global servicemanager - nsServiceManager::ShutdownGlobalServiceManager(NULL); - + nsComponentManagerImpl::gComponentManager->FreeServices(); + nsServiceManager::ShutdownGlobalServiceManager(nsnull); + if (currentQ) { currentQ->ProcessPendingEvents(); currentQ = 0; diff --git a/xpcom/components/MANIFEST b/xpcom/components/MANIFEST index a7d78fc9c80..e51972d5681 100644 --- a/xpcom/components/MANIFEST +++ b/xpcom/components/MANIFEST @@ -1,6 +1,7 @@ nsIGenericFactory.h nsIRegistryUtils.h -nsIServiceManager.h nsXPComFactory.h nsComponentManagerUtils.h nsStaticComponent.h +nsIServiceManagerObsolete.h +nsIServiceManagerUtils.h diff --git a/xpcom/components/MANIFEST_IDL b/xpcom/components/MANIFEST_IDL index 9c297b038d3..a4e53b69048 100644 --- a/xpcom/components/MANIFEST_IDL +++ b/xpcom/components/MANIFEST_IDL @@ -5,3 +5,4 @@ nsIComponentLoader.idl nsIComponentManager.idl nsIFactory.idl nsIRegistry.idl +nsIServiceManager.idl diff --git a/xpcom/components/Makefile.in b/xpcom/components/Makefile.in index 869429f181f..9faf1c9ea3f 100644 --- a/xpcom/components/Makefile.in +++ b/xpcom/components/Makefile.in @@ -34,11 +34,12 @@ REQUIRES = libreg \ $(NULL) CPPSRCS = \ + nsCategoryManager.cpp \ nsComponentManager.cpp \ nsGenericFactory.cpp \ nsNativeComponentLoader.cpp \ nsRegistry.cpp \ - nsCategoryManager.cpp \ + nsServiceManagerObsolete.cpp \ xcDll.cpp \ $(NULL) @@ -52,7 +53,8 @@ EXPORTS = \ nsComponentManagerUtils.h \ nsIGenericFactory.h \ nsIRegistryUtils.h \ - nsIServiceManager.h \ + nsIServiceManagerUtils.h \ + nsIServiceManagerObsolete.h \ nsXPComFactory.h \ nsStaticComponent.h \ $(NULL) @@ -66,6 +68,7 @@ XPIDLSRCS = \ nsIFactory.idl \ nsIModule.idl \ nsIRegistry.idl \ + nsIServiceManager.idl \ $(NULL) EXPORTS := $(addprefix $(srcdir)/, $(EXPORTS)) diff --git a/xpcom/components/makefile.win b/xpcom/components/makefile.win index ed6596d392a..d5f794ebd89 100644 --- a/xpcom/components/makefile.win +++ b/xpcom/components/makefile.win @@ -35,7 +35,8 @@ EXPORTS = \ nsComponentManagerUtils.h \ nsIGenericFactory.h \ nsIRegistryUtils.h \ - nsIServiceManager.h \ + nsIServiceManagerObsolete.h \ + nsIServiceManagerUtils.h \ nsXPComFactory.h \ nsNativeComponentLoader.h \ nsStaticComponent.h \ @@ -51,6 +52,7 @@ XPIDLSRCS = \ .\nsIFactory.idl \ .\nsIModule.idl \ .\nsIRegistry.idl \ + .\nsIServiceManager.idl \ $(NULL) ################################################################################ @@ -74,7 +76,8 @@ CPP_OBJS = \ .\$(OBJDIR)\nsComponentManager.obj \ .\$(OBJDIR)\nsGenericFactory.obj \ .\$(OBJDIR)\nsNativeComponentLoader.obj \ - .\$(OBJDIR)\nsStaticComponentLoader.obj \ + .\$(OBJDIR)\nsServiceManagerObsolete.obj \ + .\$(OBJDIR)\nsStaticComponentLoader.obj \ .\$(OBJDIR)\nsRegistry.obj \ .\$(OBJDIR)\nsCategoryManager.obj \ .\$(OBJDIR)\xcDll.obj \ diff --git a/xpcom/components/nsCategoryManager.cpp b/xpcom/components/nsCategoryManager.cpp index b8cc51b6e7d..4d717228733 100644 --- a/xpcom/components/nsCategoryManager.cpp +++ b/xpcom/components/nsCategoryManager.cpp @@ -43,6 +43,7 @@ #include "nsIFactory.h" #include "nsIRegistry.h" #include "nsISupportsPrimitives.h" +#include "nsIObserver.h" #include "nsComponentManager.h" #include "nsHashtableEnumerator.h" @@ -584,3 +585,68 @@ NS_CategoryManagerGetFactory( nsIFactory** aFactory ) return status; } + + + +/* + * CreateServicesFromCategory() + * + * Given a category, this convenience functions enumerates the category and + * creates a service of every CID or ContractID registered under the category. + * If observerTopic is non null and the service implements nsIObserver, + * this will attempt to notify the observer with the origin, observerTopic string + * as parameter. + */ +nsresult +NS_CreateServicesFromCategory(const char *category, + nsISupports *origin, + const PRUnichar *observerTopic) +{ + nsresult rv = NS_OK; + + int nFailed = 0; + nsCOMPtr categoryManager = + do_GetService("@mozilla.org/categorymanager;1", &rv); + if (!categoryManager) return rv; + + nsCOMPtr enumerator; + rv = categoryManager->EnumerateCategory(category, + getter_AddRefs(enumerator)); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr entry; + while (NS_SUCCEEDED(enumerator->GetNext(getter_AddRefs(entry)))) { + // From here on just skip any error we get. + nsCOMPtr catEntry = do_QueryInterface(entry, &rv); + if (NS_FAILED(rv)) { + nFailed++; + continue; + } + nsXPIDLCString entryString; + rv = catEntry->GetData(getter_Copies(entryString)); + if (NS_FAILED(rv)) { + nFailed++; + continue; + } + nsXPIDLCString contractID; + rv = categoryManager->GetCategoryEntry(category,(const char *)entryString, getter_Copies(contractID)); + if (NS_FAILED(rv)) { + nFailed++; + continue; + } + + nsCOMPtr instance = do_GetService(contractID, &rv); + if (NS_FAILED(rv)) { + nFailed++; + continue; + } + + if (observerTopic) { + // try an observer, if it implements it. + nsCOMPtr observer = do_QueryInterface(instance, &rv); + if (NS_SUCCEEDED(rv) && observer) + observer->Observe(origin, observerTopic, NS_LITERAL_STRING("").get()); + } + } + return (nFailed ? NS_ERROR_FAILURE : NS_OK); +} diff --git a/xpcom/components/nsComponentManager.cpp b/xpcom/components/nsComponentManager.cpp index 77d7d0907b5..243bf3aab59 100644 --- a/xpcom/components/nsComponentManager.cpp +++ b/xpcom/components/nsComponentManager.cpp @@ -31,6 +31,9 @@ #include #include "nscore.h" #include "nsISupports.h" +#include "nsCRT.h" +#include "nspr.h" + // this after nsISupports, to pick up IID // so that xpt stuff doesn't try to define it itself... #include "xptinfo.h" @@ -38,9 +41,8 @@ #include "nsCOMPtr.h" #include "nsComponentManager.h" -#include "nsIServiceManager.h" #include "nsICategoryManager.h" -#include "nsCRT.h" + #include "nsIEnumerator.h" #include "nsIModule.h" #include "nsHashtableEnumerator.h" @@ -51,20 +53,10 @@ #include "nsIObserverService.h" -#include "nsILocalFile.h" #include "nsLocalFile.h" #include "nsDirectoryService.h" #include "nsDirectoryServiceDefs.h" -#include "plstr.h" -#include "prlink.h" -#include "prsystem.h" -#include "prprf.h" -#include "xcDll.h" -#include "prerror.h" -#include "prmem.h" -#include "nsIFile.h" -//#include "mozreg.h" #include "NSReg.h" #include "prcmon.h" @@ -133,9 +125,7 @@ static nsFactoryEntry * kNonExistentContractID = (nsFactoryEntry*) 1; NS_DEFINE_CID(kEmptyCID, NS_EMPTY_IID); - -nsIServiceManager* gServiceManager = NULL; -PRBool gShuttingDown = PR_FALSE; +extern PRBool gXPCOMShuttingDown; // Build is using USE_NSREG to turn off xpcom using registry // but internally we use USE_REGISTRY. Map them propertly. @@ -217,15 +207,17 @@ nsCreateInstanceFromCategory::operator()( const nsIID& aIID, nsresult nsGetServiceByCID::operator()( const nsIID& aIID, void** aInstancePtr ) const { - nsresult status; - // Too bad |nsServiceManager| isn't an |nsIServiceManager|, then this could have been one call - if ( mServiceManager ) - status = mServiceManager->GetService(mCID, aIID, NS_REINTERPRET_CAST(nsISupports**, aInstancePtr), 0); - else - status = nsServiceManager::GetService(mCID, aIID, NS_REINTERPRET_CAST(nsISupports**, aInstancePtr), 0); - - if ( !NS_SUCCEEDED(status) ) - *aInstancePtr = 0; + nsresult status = NS_ERROR_FAILURE; + if ( mServiceManager ) { + status = mServiceManager->GetService(mCID, aIID, (void**)aInstancePtr); + } else { + nsCOMPtr mgr; + NS_GetServiceManager(getter_AddRefs(mgr)); + if (mgr) + status = mgr->GetService(mCID, aIID, (void**)aInstancePtr); + } + if ( !NS_SUCCEEDED(status) ) + *aInstancePtr = 0; if ( mErrorPtr ) *mErrorPtr = status; @@ -235,25 +227,23 @@ nsGetServiceByCID::operator()( const nsIID& aIID, void** aInstancePtr ) const nsresult nsGetServiceByContractID::operator()( const nsIID& aIID, void** aInstancePtr ) const { - nsresult status; - if ( mContractID ) - { - // Too bad |nsServiceManager| isn't an |nsIServiceManager|, then this could have been one call - if ( mServiceManager ) - status = mServiceManager->GetService(mContractID, aIID, NS_REINTERPRET_CAST(nsISupports**, aInstancePtr), 0); - else - status = nsServiceManager::GetService(mContractID, aIID, NS_REINTERPRET_CAST(nsISupports**, aInstancePtr), 0); - - if ( !NS_SUCCEEDED(status) ) - *aInstancePtr = 0; - } - else - status = NS_ERROR_NULL_POINTER; + nsresult status = NS_ERROR_FAILURE; + if ( mServiceManager ) { + status = mServiceManager->GetServiceByContractID(mContractID, aIID, (void**)aInstancePtr); + } else { + nsCOMPtr mgr; + NS_GetServiceManager(getter_AddRefs(mgr)); + if (mgr) + status = mgr->GetServiceByContractID(mContractID, aIID, (void**)aInstancePtr); + } + + if ( !NS_SUCCEEDED(status) ) + *aInstancePtr = 0; if ( mErrorPtr ) *mErrorPtr = status; return status; - } +} nsresult nsGetServiceFromCategory::operator()( const nsIID& aIID, void** aInstancePtr) @@ -281,18 +271,15 @@ nsGetServiceFromCategory::operator()( const nsIID& aIID, void** aInstancePtr) goto error; } - // Too bad |nsServiceManager| isn't an |nsIServiceManager|, then - // this could have been one call. - if ( mServiceManager ) - status = - mServiceManager->GetService(value, aIID, - NS_REINTERPRET_CAST(nsISupports**, - aInstancePtr), 0); - else - status = - nsServiceManager::GetService(value, aIID, - NS_REINTERPRET_CAST(nsISupports**, - aInstancePtr), 0); + if ( mServiceManager ) { + status = mServiceManager->GetServiceByContractID(value, aIID, (void**)aInstancePtr); + } else { + nsCOMPtr mgr; + NS_GetServiceManager(getter_AddRefs(mgr)); + if (mgr) + status = mgr->GetServiceByContractID(value, aIID, (void**)aInstancePtr); + } + if (NS_FAILED(status)) { error: *aInstancePtr = 0; @@ -302,133 +289,6 @@ nsGetServiceFromCategory::operator()( const nsIID& aIID, void** aInstancePtr) return status; } - -/* - * CreateServicesFromCategory() - * - * Given a category, this convenience functions enumerates the category and - * creates a service of every CID or ContractID registered under the category. - * If observerTopic is non null and the service implements nsIObserver, - * this will attempt to notify the observer with the origin, observerTopic string - * as parameter. - */ -nsresult -NS_CreateServicesFromCategory(const char *category, - nsISupports *origin, - const PRUnichar *observerTopic) -{ - nsresult rv = NS_OK; - - int nFailed = 0; - nsCOMPtr categoryManager = - do_GetService("@mozilla.org/categorymanager;1", &rv); - if (!categoryManager) return rv; - - nsCOMPtr enumerator; - rv = categoryManager->EnumerateCategory(category, - getter_AddRefs(enumerator)); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr entry; - while (NS_SUCCEEDED(enumerator->GetNext(getter_AddRefs(entry)))) { - // From here on just skip any error we get. - nsCOMPtr catEntry = do_QueryInterface(entry, &rv); - if (NS_FAILED(rv)) { - nFailed++; - continue; - } - nsXPIDLCString entryString; - rv = catEntry->GetData(getter_Copies(entryString)); - if (NS_FAILED(rv)) { - nFailed++; - continue; - } - nsXPIDLCString contractID; - rv = categoryManager->GetCategoryEntry(category,(const char *)entryString, getter_Copies(contractID)); - if (NS_FAILED(rv)) { - nFailed++; - continue; - } - - nsCOMPtr instance = do_GetService(contractID, &rv); - if (NS_FAILED(rv)) { - nFailed++; - continue; - } - - if (observerTopic) { - // try an observer, if it implements it. - nsCOMPtr observer = do_QueryInterface(instance, &rv); - if (NS_SUCCEEDED(rv) && observer) - observer->Observe(origin, observerTopic, NS_LITERAL_STRING("").get()); - } - } - return (nFailed ? NS_ERROR_FAILURE : NS_OK); -} - -// Get a service with control to not create it -// The right way to do this is to add this into the nsIServiceManager -// api. Changing the api however will break a whole bunch of modules - -// plugins and other embedding clients. So until we figure out how to -// make new apis and maintain backward compabitility etc, we are adding -// this api. -// -// WARNING: USE AT YOUR OWN RISK. THIS FUNCTION WILL NOT BE SUPPORTED -// IN FUTURE RELEASES. -NS_COM nsresult -NS_GetService(const char *aContractID, const nsIID& aIID, PRBool aDontCreate, nsISupports** result) -{ - if (!aDontCreate) { - // This is the same as the old get service. - return nsServiceManager::GetService(aContractID, aIID, result, nsnull); - } - nsComponentManagerImpl* mgr; - nsresult rv = NS_GetGlobalComponentManager((nsIComponentManager **)&mgr); - if (NS_FAILED(rv)) - return rv; - - return mgr->FetchService(aContractID, aIID, result); -} - -nsresult -nsComponentManagerImpl::FetchService(const char *aContractID, const nsIID& aIID, nsISupports** result) -{ - // Now we want to get the service if we already got it. If not, we dont want - // to create an instance of it. mmh! - - // test this first, since there's no point in returning a service during - // shutdown -- whether it's available or not would depend on the order it - // occurs in the list - if (gShuttingDown) { - // When processing shutdown, dont process new GetService() requests - NS_WARNING("Creating new service on shutdown. Denied."); - return NS_ERROR_UNEXPECTED; - } - - nsresult rv = NS_ERROR_SERVICE_NOT_FOUND; - nsCStringKey key(aContractID); - nsFactoryEntry *entry = (nsFactoryEntry *) mContractIDs->Get(&key); - nsServiceEntry* serviceEntry; - if (entry && entry != kNonExistentContractID && entry->mServiceEntry) { - serviceEntry = entry->mServiceEntry; - - if (!serviceEntry->mObject) - return NS_ERROR_NULL_POINTER; - nsISupports* service; // keep as raw point (avoid extra addref/release) - rv = serviceEntry->mObject->QueryInterface(aIID, (void**)&service); - *result = service; - // If someone else requested the service to be shut down, - // and we just asked to get it again before it could be - // released, then cancel their shutdown request: - if (serviceEntry->mShuttingDown) { - serviceEntry->mShuttingDown = PR_FALSE; - NS_ADDREF(service); // Released in UnregisterService - } - } - return rv; -} - - /* prototypes for the Mac */ PRBool PR_CALLBACK nsFactoryEntry_Destroy(nsHashKey *aKey, void *aData, void* closure); @@ -448,11 +308,7 @@ nsServiceEntry::nsServiceEntry(nsISupports* service, nsFactoryEntry* factEntry) nsServiceEntry::~nsServiceEntry() { NotifyListeners(); - - //special case the nsComponentManagerImpl. - // XXX review-notes we need to see why we need to do this - if ((void*)mObject != (void*)nsComponentManagerImpl::gComponentManager) - NS_IF_RELEASE(mObject); + NS_IF_RELEASE(mObject); } nsresult @@ -746,11 +602,11 @@ nsComponentManagerImpl::~nsComponentManagerImpl() PR_LOG(nsComponentManagerLog, PR_LOG_ALWAYS, ("nsComponentManager: Destroyed.")); } -NS_IMPL_ISUPPORTS4(nsComponentManagerImpl, - nsIComponentManager, - nsIServiceManager, - nsISupportsWeakReference, - nsIInterfaceRequestor) +NS_IMPL_THREADSAFE_ISUPPORTS4(nsComponentManagerImpl, + nsIComponentManager, + nsIServiceManager, + nsISupportsWeakReference, + nsIInterfaceRequestor) //////////////////////////////////////////////////////////////////////////////// // nsComponentManagerImpl: Platform methods @@ -1585,7 +1441,7 @@ nsComponentManagerImpl::CreateInstance(const nsCID &aClass, // test this first, since there's no point in creating a component during // shutdown -- whether it's available or not would depend on the order it // occurs in the list - if (gShuttingDown) { + if (gXPCOMShuttingDown) { // When processing shutdown, dont process new GetService() requests #ifdef DEBUG_dp NS_WARN_IF_FALSE(PR_FALSE, "Creating new instance on shutdown. Denied."); @@ -1642,7 +1498,7 @@ nsComponentManagerImpl::CreateInstanceByContractID(const char *aContractID, // test this first, since there's no point in creating a component during // shutdown -- whether it's available or not would depend on the order it // occurs in the list - if (gShuttingDown) { + if (gXPCOMShuttingDown) { // When processing shutdown, dont process new GetService() requests #ifdef DEBUG_dp NS_WARN_IF_FALSE(PR_FALSE, "Creating new instance on shutdown. Denied."); @@ -1704,16 +1560,16 @@ nsComponentManagerImpl::FreeServices() return NS_OK; } NS_IMETHODIMP -nsComponentManagerImpl::GetService(const nsCID& aClass, const nsIID& aIID, - nsISupports* *result, - nsIShutdownListener* shutdownListener) +nsComponentManagerImpl::GetService(const nsCID& aClass, + const nsIID& aIID, + void* *result) { nsAutoMonitor mon(mMon); // test this first, since there's no point in returning a service during // shutdown -- whether it's available or not would depend on the order it // occurs in the list - if (gShuttingDown) { + if (gXPCOMShuttingDown) { // When processing shutdown, dont process new GetService() requests NS_WARNING("Creating new service on shutdown. Denied."); return NS_ERROR_UNEXPECTED; @@ -1734,14 +1590,6 @@ nsComponentManagerImpl::GetService(const nsCID& aClass, const nsIID& aIID, if (NS_SUCCEEDED(rv)) { // The refcount acquired in QI() above is "returned" to // the caller. - if (shutdownListener) { - rv = serviceEntry->AddListener(shutdownListener); - if (NS_FAILED(rv)) { - NS_RELEASE(service); - return rv; - } - } - *result = service; // If someone else requested the service to be shut down, @@ -1778,59 +1626,11 @@ nsComponentManagerImpl::GetService(const nsCID& aClass, const nsIID& aIID, return NS_ERROR_OUT_OF_MEMORY; } - if (shutdownListener) { - rv = serviceEntry->AddListener(shutdownListener); - if (NS_FAILED(rv)) { - NS_RELEASE(service); - delete serviceEntry; - return rv; - } - } entry->mServiceEntry = serviceEntry; // deleted in nsFactoryEntry's destructor *result = service; // transfer ownership return rv; } -NS_IMETHODIMP -nsComponentManagerImpl::ReleaseService(const nsCID& aClass, nsISupports* service, - nsIShutdownListener* shutdownListener) -{ - PRBool serviceFound = PR_FALSE; - nsresult rv = NS_OK; - -#ifndef NS_DEBUG - // Do entry lookup only if there is a shutdownlistener to be removed. - // - // For Debug builds, Consistency check for entry always. Releasing service - // when the service is not with the servicemanager is mostly wrong. - if (shutdownListener) -#endif - { - nsAutoMonitor mon(mMon); - nsIDKey key(aClass); - nsFactoryEntry* entry = (nsFactoryEntry*)mFactories->Get(&key); - - if (entry && entry->mServiceEntry) { - rv = entry->mServiceEntry->RemoveListener(shutdownListener); - serviceFound = PR_TRUE; - } - } - - nsrefcnt cnt; - NS_RELEASE2(service, cnt); - - // Consistency check: Service ref count cannot go to zero because of the - // extra addref the service manager does, unless the service has been - // unregistered (ie) not found in the service managers hash table. - // - NS_ASSERTION(cnt > 0 || !serviceFound, - "*** Service in hash table but is being deleted. Dangling pointer\n" - "*** in service manager hash table."); - - return rv; -} - - NS_IMETHODIMP nsComponentManagerImpl::RegisterService(const nsCID& aClass, nsISupports* aService) { @@ -1878,7 +1678,7 @@ nsComponentManagerImpl::UnregisterService(const nsCID& aClass) } NS_IMETHODIMP -nsComponentManagerImpl::RegisterService(const char* aContractID, nsISupports* aService) +nsComponentManagerImpl::RegisterServiceByContractID(const char* aContractID, nsISupports* aService) { nsAutoMonitor mon(mMon); @@ -1909,8 +1709,90 @@ nsComponentManagerImpl::RegisterService(const char* aContractID, nsISupports* aS return NS_OK; } + +NS_IMETHODIMP +nsComponentManagerImpl::IsServiceInstantiated(const nsCID & aClass, + const nsIID& aIID, + PRBool *result) +{ + // Now we want to get the service if we already got it. If not, we dont want + // to create an instance of it. mmh! + + // test this first, since there's no point in returning a service during + // shutdown -- whether it's available or not would depend on the order it + // occurs in the list + if (gXPCOMShuttingDown) { + // When processing shutdown, dont process new GetService() requests + NS_WARNING("Creating new service on shutdown. Denied."); + return NS_ERROR_UNEXPECTED; + } + + nsresult rv = NS_ERROR_SERVICE_NOT_FOUND; + nsIDKey key(aClass); + nsFactoryEntry *entry = (nsFactoryEntry *) mFactories->Get(&key); + nsServiceEntry* serviceEntry; + if (entry && entry->mServiceEntry) { + serviceEntry = entry->mServiceEntry; + + if (!serviceEntry->mObject) + return NS_ERROR_NULL_POINTER; + nsISupports* service; // keep as raw point (avoid extra addref/release) + rv = serviceEntry->mObject->QueryInterface(aIID, (void**)&service); + *result =(service!=nsnull); + // If someone else requested the service to be shut down, + // and we just asked to get it again before it could be + // released, then cancel their shutdown request: + if (serviceEntry->mShuttingDown) { + serviceEntry->mShuttingDown = PR_FALSE; + NS_ADDREF(service); // Released in UnregisterService + } + } + return rv; + +} + +NS_IMETHODIMP nsComponentManagerImpl::IsServiceInstantiatedByContractID(const char *aContractID, + const nsIID& aIID, + PRBool *result) +{ + // Now we want to get the service if we already got it. If not, we dont want + // to create an instance of it. mmh! + + // test this first, since there's no point in returning a service during + // shutdown -- whether it's available or not would depend on the order it + // occurs in the list + if (gXPCOMShuttingDown) { + // When processing shutdown, dont process new GetService() requests + NS_WARNING("checking for new service on shutdown. Denied."); + return NS_ERROR_UNEXPECTED; + } + + nsresult rv = NS_ERROR_SERVICE_NOT_FOUND; + nsCStringKey key(aContractID); + nsFactoryEntry *entry = (nsFactoryEntry *) mContractIDs->Get(&key); + nsServiceEntry* serviceEntry; + if (entry && entry != kNonExistentContractID && entry->mServiceEntry) { + serviceEntry = entry->mServiceEntry; + + if (!serviceEntry->mObject) + return NS_ERROR_NULL_POINTER; + nsISupports* service; // keep as raw point (avoid extra addref/release) + rv = serviceEntry->mObject->QueryInterface(aIID, (void**)&service); + *result =(service!=nsnull); + // If someone else requested the service to be shut down, + // and we just asked to get it again before it could be + // released, then cancel their shutdown request: + if (serviceEntry->mShuttingDown) { + serviceEntry->mShuttingDown = PR_FALSE; + NS_ADDREF(service); // Released in UnregisterService + } + } + return rv; +} + + NS_IMETHODIMP -nsComponentManagerImpl::UnregisterService(const char* aContractID) +nsComponentManagerImpl::UnregisterServiceByContractID(const char* aContractID) { nsresult rv = NS_OK; nsAutoMonitor mon(mMon); @@ -1927,16 +1809,16 @@ nsComponentManagerImpl::UnregisterService(const char* aContractID) } NS_IMETHODIMP -nsComponentManagerImpl::GetService(const char* aContractID, const nsIID& aIID, - nsISupports* *result, - nsIShutdownListener* shutdownListener) +nsComponentManagerImpl::GetServiceByContractID(const char* aContractID, + const nsIID& aIID, + void* *result) { nsAutoMonitor mon(mMon); // test this first, since there's no point in returning a service during // shutdown -- whether it's available or not would depend on the order it // occurs in the list - if (gShuttingDown) { + if (gXPCOMShuttingDown) { // When processing shutdown, dont process new GetService() requests NS_WARNING("Creating new service on shutdown. Denied."); return NS_ERROR_UNEXPECTED; @@ -1957,14 +1839,6 @@ nsComponentManagerImpl::GetService(const char* aContractID, const nsIID& aIID, if (NS_SUCCEEDED(rv)) { // The refcount acquired in QI() above is "returned" to // the caller. - if (shutdownListener) { - rv = serviceEntry->AddListener(shutdownListener); - if (NS_FAILED(rv)) { - NS_RELEASE(service); - return rv; - } - } - *result = service; // If someone else requested the service to be shut down, @@ -2001,59 +1875,11 @@ nsComponentManagerImpl::GetService(const char* aContractID, const nsIID& aIID, return NS_ERROR_OUT_OF_MEMORY; } - if (shutdownListener) { - rv = serviceEntry->AddListener(shutdownListener); - if (NS_FAILED(rv)) { - NS_RELEASE(service); - delete serviceEntry; - return rv; - } - } entry->mServiceEntry = serviceEntry; // deleted in nsFactoryEntry's destructor *result = service; // transfer ownership return rv; } -NS_IMETHODIMP -nsComponentManagerImpl::ReleaseService(const char* aContractID, nsISupports* service, - nsIShutdownListener* shutdownListener) -{ - PRBool serviceFound = PR_FALSE; - nsresult rv = NS_OK; - -#ifndef NS_DEBUG - // Do entry lookup only if there is a shutdownlistener to be removed. - // - // For Debug builds, Consistency check for entry always. Releasing service - // when the service is not with the servicemanager is mostly wrong. - if (shutdownListener) -#endif - { - nsAutoMonitor mon(mMon); - nsCStringKey key(aContractID); - nsFactoryEntry* entry = (nsFactoryEntry*)mContractIDs->Get(&key); - - if (entry && entry->mServiceEntry) { - rv = entry->mServiceEntry->RemoveListener(shutdownListener); - serviceFound = PR_TRUE; - } - } - - nsrefcnt cnt; - NS_RELEASE2(service, cnt); - - // Consistency check: Service ref count cannot go to zero because of the - // extra addref the service manager does, unless the service has been - // unregistered (ie) not found in the service managers hash table. - // - NS_ASSERTION(cnt > 0 || !serviceFound, - "*** Service in hash table but is being deleted. Dangling pointer\n" - "*** in service manager hash table."); - - return rv; -} - - /* * I want an efficient way to allocate a buffer to the right size @@ -2632,11 +2458,7 @@ nsComponentManagerImpl::UnregisterComponentSpec(const nsCID &aClass, nsresult nsComponentManagerImpl::FreeLibraries(void) { - nsIServiceManager* serviceMgr = NULL; - nsresult rv = nsServiceManager::GetGlobalServiceManager(&serviceMgr); - if (NS_FAILED(rv)) return rv; - rv = UnloadLibraries(serviceMgr, NS_Timer); // XXX when - return rv; + return UnloadLibraries(NS_STATIC_CAST(nsIServiceManager*, this), NS_Timer); // XXX when } // Private implementation of unloading libraries @@ -2746,15 +2568,11 @@ nsComponentManagerImpl::AutoRegisterImpl(PRInt32 when, nsIFile *inDirSpec) do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv); if (NS_FAILED(rv)) { - - nsIServiceManager *mgr; // NO COMPtr as we dont release the service manager - rv = nsServiceManager::GetGlobalServiceManager(&mgr); - if (NS_SUCCEEDED(rv)) - { - (void) observerService->Notify(mgr, - NS_ConvertASCIItoUCS2(NS_XPCOM_AUTOREGISTRATION_OBSERVER_ID).get(), - NS_ConvertASCIItoUCS2("Starting component registration").get()); - } + // NO COMPtr as we dont release the service manager + nsIServiceManager *mgr = NS_STATIC_CAST(nsIServiceManager*, this); + (void) observerService->Notify(mgr, + NS_ConvertASCIItoUCS2(NS_XPCOM_AUTOREGISTRATION_OBSERVER_ID).get(), + NS_ConvertASCIItoUCS2("Starting component registration").get()); } /* do the native loader first, so we can find other loaders */ @@ -2822,16 +2640,12 @@ nsComponentManagerImpl::AutoRegisterImpl(PRInt32 when, nsIFile *inDirSpec) } } while (NS_SUCCEEDED(rv) && registered); } - - nsIServiceManager *mgr; // NO COMPtr as we dont release the service manager - rv = nsServiceManager::GetGlobalServiceManager(&mgr); - if (NS_SUCCEEDED(rv)) - { - (void) observerService->Notify(mgr, - NS_ConvertASCIItoUCS2(NS_XPCOM_AUTOREGISTRATION_OBSERVER_ID).get(), - NS_ConvertASCIItoUCS2("Component registration finished").get()); - } - + + // NO COMPtr as we dont release the service manager + nsIServiceManager *mgr = NS_STATIC_CAST(nsIServiceManager*, this); + (void) observerService->Notify(mgr, + NS_ConvertASCIItoUCS2(NS_XPCOM_AUTOREGISTRATION_OBSERVER_ID).get(), + NS_ConvertASCIItoUCS2("Component registration finished").get()); return rv; } @@ -2983,16 +2797,14 @@ nsComponentManagerImpl::GetInterface(const nsIID & uuid, void **result) nsresult rv = NS_OK; if (uuid.Equals(NS_GET_IID(nsIServiceManager))) { - // Return the global service manager - rv = nsServiceManager::GetGlobalServiceManager((nsIServiceManager **)result); + *result = NS_STATIC_CAST(nsIServiceManager*, this); + NS_ADDREF_THIS(); // dougt? extra addrefs??? + return NS_OK; } - else - { - // fall through to QI as anything QIable is a superset of what canbe - // got via the GetInterface() - rv = QueryInterface(uuid, result); - } - return rv; + + // fall through to QI as anything QIable is a superset of what canbe + // got via the GetInterface() + return QueryInterface(uuid, result); } // Convert a loader type string into an index into the component data @@ -3058,7 +2870,7 @@ NS_GetGlobalComponentManager(nsIComponentManager* *result) if (nsComponentManagerImpl::gComponentManager == NULL) { // XPCOM needs initialization. - rv = NS_InitXPCOM(NULL, NULL); + rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); } if (NS_SUCCEEDED(rv)) @@ -3070,6 +2882,27 @@ NS_GetGlobalComponentManager(nsIComponentManager* *result) return rv; } +NS_COM nsresult +NS_GetServiceManager(nsIServiceManager* *result) +{ + nsresult rv = NS_OK; + + if (nsComponentManagerImpl::gComponentManager == NULL) + { + // XPCOM needs initialization. + rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); + } + + if (NS_FAILED(rv)) + return rv; + + + *result = NS_STATIC_CAST(nsIServiceManager*, + nsComponentManagerImpl::gComponentManager); + NS_IF_ADDREF(*result); + return NS_OK; +} + //////////////////////////////////////////////////////////////////////////////// @@ -3301,133 +3134,3 @@ nsComponentManager::EnumerateContractIDs(nsIEnumerator** aEmumerator) return cm->EnumerateContractIDs(aEmumerator); } -//////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// -// Global service manager interface (see nsIServiceManager.h) - -nsresult -nsServiceManager::GetGlobalServiceManager(nsIServiceManager* *result) -{ - if (gShuttingDown) - return NS_ERROR_UNEXPECTED; - - nsresult rv = NS_OK; - if (gServiceManager == NULL) { - // XPCOM not initialized yet. Let us do initialization of our module. - rv = NS_InitXPCOM(NULL, NULL); - } - // No ADDREF as we are advicing no release of this. - if (NS_SUCCEEDED(rv)) - *result = gServiceManager; - - return rv; -} - -nsresult -nsServiceManager::ShutdownGlobalServiceManager(nsIServiceManager* *result) -{ - if (gServiceManager != NULL) { - nsrefcnt cnt; - - nsComponentManagerImpl* compImpl = NS_STATIC_CAST(nsComponentManagerImpl*, gServiceManager); - compImpl->FreeServices(); - - NS_RELEASE2(gServiceManager, cnt); - // the only reference at this point should be the component manager. - NS_ASSERTION(cnt == 1, "Service Manager being held past XPCOM shutdown."); - gServiceManager = NULL; - } - return NS_OK; -} - -nsresult -nsServiceManager::GetService(const nsCID& aClass, const nsIID& aIID, - nsISupports* *result, - nsIShutdownListener* shutdownListener) -{ - nsIServiceManager* mgr; - nsresult rv = GetGlobalServiceManager(&mgr); - if (NS_FAILED(rv)) return rv; - return mgr->GetService(aClass, aIID, result, shutdownListener); -} - -nsresult -nsServiceManager::ReleaseService(const nsCID& aClass, nsISupports* service, - nsIShutdownListener* shutdownListener) -{ - // Don't create the global service manager here because we might be shutting - // down, and releasing all the services in its destructor - if (gServiceManager) - return gServiceManager->ReleaseService(aClass, service, shutdownListener); - // If there wasn't a global service manager, just release the object: - NS_RELEASE(service); - return NS_OK; -} - -nsresult -nsServiceManager::RegisterService(const nsCID& aClass, nsISupports* aService) -{ - nsIServiceManager* mgr; - nsresult rv = GetGlobalServiceManager(&mgr); - if (NS_FAILED(rv)) return rv; - return mgr->RegisterService(aClass, aService); -} - -nsresult -nsServiceManager::UnregisterService(const nsCID& aClass) -{ - nsIServiceManager* mgr; - nsresult rv = GetGlobalServiceManager(&mgr); - if (NS_FAILED(rv)) return rv; - return mgr->UnregisterService(aClass); -} - -//////////////////////////////////////////////////////////////////////////////// -// let's do it again, this time with ContractIDs... - -nsresult -nsServiceManager::GetService(const char* aContractID, const nsIID& aIID, - nsISupports* *result, - nsIShutdownListener* shutdownListener) -{ - nsIServiceManager* mgr; - nsresult rv = GetGlobalServiceManager(&mgr); - if (NS_FAILED(rv)) return rv; - return mgr->GetService(aContractID, aIID, result, shutdownListener); -} - -nsresult -nsServiceManager::ReleaseService(const char* aContractID, nsISupports* service, - nsIShutdownListener* shutdownListener) -{ - // Don't create the global service manager here because we might - // be shutting down, and releasing all the services in its - // destructor - if (gServiceManager) - return gServiceManager->ReleaseService(aContractID, service, shutdownListener); - // If there wasn't a global service manager, just release the object: - NS_RELEASE(service); - return NS_OK; -} - -nsresult -nsServiceManager::RegisterService(const char* aContractID, nsISupports* aService) -{ - nsIServiceManager* mgr; - nsresult rv = GetGlobalServiceManager(&mgr); - if (NS_FAILED(rv)) return rv; - return mgr->RegisterService(aContractID, aService); -} - -nsresult -nsServiceManager::UnregisterService(const char* aContractID) -{ - // Don't create the global service manager here because we might - // be shutting down, and releasing all the services in its - // destructor - if (gServiceManager) - return gServiceManager->UnregisterService(aContractID); - return NS_OK; -} - -//////////////////////////////////////////////////////////////////////////////// diff --git a/xpcom/components/nsComponentManager.h b/xpcom/components/nsComponentManager.h index 71dfb553940..5f5a647b195 100644 --- a/xpcom/components/nsComponentManager.h +++ b/xpcom/components/nsComponentManager.h @@ -38,6 +38,8 @@ #ifndef nsComponentManager_h__ #define nsComponentManager_h__ +#include "nsXPCOM.h" + #include "nsIComponentLoader.h" #include "nsNativeComponentLoader.h" #include "nsIComponentManager.h" @@ -84,39 +86,15 @@ class nsComponentManagerImpl public nsIInterfaceRequestor { public: NS_DECL_ISUPPORTS - NS_DECL_NSICOMPONENTMANAGER NS_DECL_NSIINTERFACEREQUESTOR + NS_DECL_NSICOMPONENTMANAGER + NS_DECL_NSISERVICEMANAGER - // Service Manager - NS_IMETHOD - RegisterService(const nsCID& aClass, nsISupports* aService); - - NS_IMETHOD - UnregisterService(const nsCID& aClass); - - NS_IMETHOD - GetService(const nsCID& aClass, const nsIID& aIID, - nsISupports* *result, - nsIShutdownListener* shutdownListener = NULL); - - NS_IMETHOD - ReleaseService(const nsCID& aClass, nsISupports* service, - nsIShutdownListener* shutdownListener = NULL); - - NS_IMETHOD - RegisterService(const char* aContractID, nsISupports* aService); - - NS_IMETHOD - UnregisterService(const char* aContractID); - - NS_IMETHOD - GetService(const char* aContractID, const nsIID& aIID, - nsISupports* *result, - nsIShutdownListener* shutdownListener = NULL); - - NS_IMETHOD - ReleaseService(const char* aContractID, nsISupports* service, - nsIShutdownListener* shutdownListener = NULL); + // to be moved when nsIComponentManager is frozen. + NS_IMETHOD RegisterService(const nsCID & aClass, nsISupports *aService); + NS_IMETHOD RegisterServiceByContractID(const char *aContractID, nsISupports *aService); + NS_IMETHOD UnregisterService(const nsCID & aClass); + NS_IMETHOD UnregisterServiceByContractID(const char *aContractID); // nsComponentManagerImpl methods: nsComponentManagerImpl(); @@ -127,12 +105,15 @@ public: nsresult PlatformPrePopulateRegistry(); nsresult Shutdown(void); + nsresult FreeServices(); + friend class nsFactoryEntry; friend class nsServiceManager; + friend nsresult NS_GetService(const char *aContractID, const nsIID& aIID, PRBool aDontCreate, nsISupports** result); + protected: - nsresult FetchService(const char *aContractID, const nsIID& aIID, nsISupports** result); nsresult RegistryNameForLib(const char *aLibName, char **aRegistryName); nsresult RegisterComponentCommon(const nsCID &aClass, const char *aClassName, @@ -161,7 +142,6 @@ protected: nsresult HashContractID(const char *acontractID, const nsCID &aClass, nsIDKey &cidKey, nsFactoryEntry **fe_ptr = NULL); nsresult UnloadLibraries(nsIServiceManager *servmgr, PRInt32 when); - nsresult FreeServices(); // The following functions are the only ones that operate on the persistent // registry nsresult PlatformInit(void); diff --git a/xpcom/components/nsICategoryManager.idl b/xpcom/components/nsICategoryManager.idl index e19ec26c300..707e7cf4eee 100644 --- a/xpcom/components/nsICategoryManager.idl +++ b/xpcom/components/nsICategoryManager.idl @@ -118,4 +118,9 @@ interface nsICategoryManager : nsISupports {0xb6, 0x93, 0xf3, 0x8b, 0x02, 0xc0, 0x21, 0xb2} } extern "C" NS_EXPORT nsresult NS_CategoryManagerGetFactory( nsIFactory** ); + +NS_COM nsresult +NS_CreateServicesFromCategory(const char *category, + nsISupports *origin, + const PRUnichar *observerTopic); %} diff --git a/xpcom/components/nsIServiceManager.idl b/xpcom/components/nsIServiceManager.idl new file mode 100644 index 00000000000..eb0a37ae248 --- /dev/null +++ b/xpcom/components/nsIServiceManager.idl @@ -0,0 +1,107 @@ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * 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 XPCOM. + * + * The Initial Developer of the Original Code is Netscape Communications. + * Portions created by the Initial Developer are Copyright (C) 2001 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +#include "nsISupports.idl" + +/** + * The nsIServiceManager manager interface provides a means to obtain + * global services in an application. The service manager depends on the + * repository to find and instantiate factories to obtain services. + * + * Users of the service manager must first obtain a pointer to the global + * service manager by calling NS_GetServiceManager. After that, + * they can request specific services by calling GetService. When they are + * finished they can NS_RELEASE() the service as usual. + * + * A user of a service may keep references to particular services indefinitely + * and only must call Release when it shuts down. + * + * @status FROZEN + */ + +[scriptable, uuid(8bb35ed9-e332-462d-9155-4a002ab5c958)] +interface nsIServiceManager : nsISupports +{ + /** + * getServiceByContractID + * + * Returns the instance that implements aClass or aContractID and the + * interface aIID. This may result in the instance being created. + * + * @param aClass or aContractID : aClass or aContractID of object + * instance requested + * @param aIID : IID of interface requested + * @param result : resulting service + */ + void getService(in nsCIDRef aClass, + in nsIIDRef aIID, + [iid_is(aIID),retval] out nsQIResult result); + + void getServiceByContractID(in string aContractID, + in nsIIDRef aIID, + [iid_is(aIID),retval] out nsQIResult result); + + /** + * isServiceInstantiated + * + * isServiceInstantiated will return a true if the service has already + * been created, otherwise false + * + * @param aClass or aContractID : aClass or aContractID of object + * instance requested + * @param aIID : IID of interface requested + * @param aIID : IID of interface requested + */ + boolean isServiceInstantiated(in nsCIDRef aClass, in nsIIDRef aIID); + boolean isServiceInstantiatedByContractID(in string aContractID, in nsIIDRef aIID); +}; + + +%{C++ +#define NS_ERROR_SERVICE_NOT_FOUND NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCOM, 22) +#define NS_ERROR_SERVICE_IN_USE NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_XPCOM, 23) + +// Observing xpcom shutdown +#define NS_XPCOM_SHUTDOWN_OBSERVER_ID "xpcom-shutdown" +#define NS_XPCOM_AUTOREGISTRATION_OBSERVER_ID "xpcom-autoregistration" + +#ifndef MOZILLA_STRICT_API +#include "nsXPCOM.h" +#include "nsIServiceManagerUtils.h" +#include "nsIServiceManagerObsolete.h" +#endif +%} + diff --git a/xpcom/components/nsIServiceManagerObsolete.h b/xpcom/components/nsIServiceManagerObsolete.h new file mode 100644 index 00000000000..b4711d4d700 --- /dev/null +++ b/xpcom/components/nsIServiceManagerObsolete.h @@ -0,0 +1,289 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape 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/NPL/ + * + * 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 XPCOM + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsIServiceManagerObsolete_h___ +#define nsIServiceManagerObsolete_h___ + +//////////////////////////////////////////////////////////////////// +// +// WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING +// +// Functions, classes, interfaces and types in this file are +// obsolete. Use at your own risk. +// Please see nsIServiceManager.idl for the supported interface +// to the service manager. +// +//////////////////////////////////////////////////////////////////// + +#include "nsIComponentManager.h" +#include "nsID.h" + +#ifndef nsCOMPtr_h___ +#include "nsCOMPtr.h" +#endif + +class nsIServiceManager; +class nsIShutdownListener; +class nsIDirectoryServiceProvider; + +class nsServiceManagerObsolete; + +#define NS_ISERVICEMANAGER_OBSOLETE_IID \ +{ /* cf0df3b0-3401-11d2-8163-006008119d7a */ \ + 0xcf0df3b0, \ + 0x3401, \ + 0x11d2, \ + {0x81, 0x63, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \ +} + +/** + * The nsIServiceManagerObsolete manager is obsolete. Please refer + * to nsIServiceManager. + */ +class nsIServiceManagerObsolete : public nsISupports { +public: + + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISERVICEMANAGER_OBSOLETE_IID); + + /** + * RegisterService may be called explicitly to register a service + * with the service manager. If a service is not registered explicitly, + * the component manager will be used to create an instance according + * to the class ID specified. + */ + NS_IMETHOD + RegisterService(const nsCID& aClass, nsISupports* aService) = 0; + + /** + * Requests a service to be shut down, possibly unloading its DLL. + * + * @returns NS_OK - if shutdown was successful and service was unloaded, + * @returns NS_ERROR_SERVICE_NOT_FOUND - if shutdown failed because + * the service was not currently loaded + * @returns NS_ERROR_SERVICE_IN_USE - if shutdown failed because some + * user of the service wouldn't voluntarily release it by using + * a shutdown listener. + */ + NS_IMETHOD + UnregisterService(const nsCID& aClass) = 0; + + NS_IMETHOD + GetService(const nsCID& aClass, const nsIID& aIID, + nsISupports* *result, + nsIShutdownListener* shutdownListener = nsnull) = 0; + + /* OBSOLETE: use NS_RELEASE(service) instead. */ + NS_IMETHOD + ReleaseService(const nsCID& aClass, nsISupports* service, + nsIShutdownListener* shutdownListener = nsnull) = 0; + + //////////////////////////////////////////////////////////////////////////// + // let's do it again, this time with ContractIDs... + + NS_IMETHOD + RegisterService(const char* aContractID, nsISupports* aService) = 0; + + NS_IMETHOD + UnregisterService(const char* aContractID) = 0; + + NS_IMETHOD + GetService(const char* aContractID, const nsIID& aIID, + nsISupports* *result, + nsIShutdownListener* shutdownListener = nsnull) = 0; + + /* OBSOLETE */ + NS_IMETHOD + ReleaseService(const char* aContractID, nsISupports* service, + nsIShutdownListener* shutdownListener = nsnull) = 0; + +}; + + +class nsServiceManagerObsolete : public nsIServiceManagerObsolete { +public: + nsServiceManagerObsolete(); + virtual ~nsServiceManagerObsolete(); + + NS_DECL_ISUPPORTS + + NS_IMETHOD + RegisterService(const nsCID& aClass, nsISupports* aService); + + NS_IMETHOD + UnregisterService(const nsCID& aClass); + + NS_IMETHOD + GetService(const nsCID& aClass, const nsIID& aIID, + nsISupports* *result, + nsIShutdownListener* shutdownListener = nsnull); + + NS_IMETHOD + ReleaseService(const nsCID& aClass, nsISupports* service, + nsIShutdownListener* shutdownListener = nsnull); + + NS_IMETHOD + RegisterService(const char* aContractID, nsISupports* aService); + + NS_IMETHOD + UnregisterService(const char* aContractID); + + NS_IMETHOD + GetService(const char* aContractID, const nsIID& aIID, + nsISupports* *result, + nsIShutdownListener* shutdownListener = nsnull); + + NS_IMETHOD + ReleaseService(const char* aContractID, nsISupports* service, + nsIShutdownListener* shutdownListener = nsnull); + +}; + + +// Interface to Global Services +class NS_COM nsServiceManager { +public: + + static nsresult + RegisterService(const nsCID& aClass, nsISupports* aService); + + static nsresult + UnregisterService(const nsCID& aClass); + + static nsresult + GetService(const nsCID& aClass, const nsIID& aIID, + nsISupports* *result, + nsIShutdownListener* shutdownListener = nsnull); + + /* OBSOLETE: use NS_RELEASE(service) instead. */ + static nsresult + ReleaseService(const nsCID& aClass, nsISupports* service, + nsIShutdownListener* shutdownListener = nsnull); + + //////////////////////////////////////////////////////////////////////////// + // let's do it again, this time with ContractIDs... + + static nsresult + RegisterService(const char* aContractID, nsISupports* aService); + + static nsresult + UnregisterService(const char* aContractID); + + static nsresult + GetService(const char* aContractID, const nsIID& aIID, + nsISupports* *result, + nsIShutdownListener* shutdownListener = nsnull); + + /* OBSOLETE: use NS_RELEASE(service) instead. */ + static nsresult + ReleaseService(const char* aContractID, nsISupports* service, + nsIShutdownListener* shutdownListener = nsnull); + + + //////////////////////////////////////////////////////////////////////////// + // These methods return really nsIServiceManagerObsolete, but they are + // statically cast to nsIServiceManager to preserve backwards compatiblity. + static nsresult GetGlobalServiceManager(nsIServiceManager* *result); + static nsresult ShutdownGlobalServiceManager(nsIServiceManager* *result); +}; + +//////////////////////////////////////////////////////////////////////////////// + +#define NS_ISHUTDOWNLISTENER_IID \ +{ /* 56decae0-3406-11d2-8163-006008119d7a */ \ + 0x56decae0, \ + 0x3406, \ + 0x11d2, \ + {0x81, 0x63, 0x00, 0x60, 0x08, 0x11, 0x9d, 0x7a} \ +} + +class nsIShutdownListener : public nsISupports { +public: + + NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISHUTDOWNLISTENER_IID); + + NS_IMETHOD + OnShutdown(const nsCID& aClass, nsISupports* service) = 0; + +}; + + + +template +inline +nsresult +CallGetService( const nsCID &aClass, + nsIShutdownListener* shutdownListener, + DestinationType** aDestination) +{ + NS_PRECONDITION(aDestination, "null parameter"); + + return nsServiceManager::GetService(aClass, + NS_GET_IID(DestinationType), + NS_REINTERPRET_CAST(nsISupports**, aDestination), + shutdownListener); +} + +template +inline +nsresult +CallGetService( const char *aContractID, + nsIShutdownListener* shutdownListener, + DestinationType** aDestination) +{ + NS_PRECONDITION(aContractID, "null parameter"); + NS_PRECONDITION(aDestination, "null parameter"); + + return nsServiceManager::GetService(aContractID, + NS_GET_IID(DestinationType), + NS_REINTERPRET_CAST(nsISupports**, aDestination), + shutdownListener); +} + +//////////////////////////////////////////////////////////////////////////////// + + +#endif /* nsIServiceManagerObsolete_h___ */ + + + + + + + + + + diff --git a/xpcom/components/nsIServiceManagerUtils.h b/xpcom/components/nsIServiceManagerUtils.h new file mode 100644 index 00000000000..a3cd61a1cfd --- /dev/null +++ b/xpcom/components/nsIServiceManagerUtils.h @@ -0,0 +1,187 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape 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/NPL/ + * + * 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 XPCOM + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsIServiceManagerUtils_h__ +#define nsIServiceManagerUtils_h__ + +#include "nsIServiceManager.h" +#include "nsIServiceManagerObsolete.h" +#include "nsCOMPtr.h" + +//////////////////////////////////////////////////////////////////////////// +// Using servicemanager with COMPtrs +class NS_COM nsGetServiceByCID : public nsCOMPtr_helper +{ + public: + nsGetServiceByCID( const nsCID& aCID, nsISupports* aServiceManager, nsresult* aErrorPtr ) + : mCID(aCID), + mServiceManager( do_QueryInterface(aServiceManager) ), + mErrorPtr(aErrorPtr) + { + // nothing else to do + } + + virtual nsresult operator()( const nsIID&, void** ) const; + virtual ~nsGetServiceByCID() {}; + + private: + const nsCID& mCID; + nsCOMPtr mServiceManager; + nsresult* mErrorPtr; +}; + +inline +const nsGetServiceByCID +do_GetService( const nsCID& aCID, nsresult* error = 0 ) +{ + return nsGetServiceByCID(aCID, 0, error); +} + +inline +const nsGetServiceByCID +do_GetService( const nsCID& aCID, nsISupports* aServiceManager, nsresult* error = 0 ) +{ + return nsGetServiceByCID(aCID, aServiceManager, error); +} + +class NS_COM nsGetServiceByContractID : public nsCOMPtr_helper +{ + public: + nsGetServiceByContractID( const char* aContractID, nsISupports* aServiceManager, nsresult* aErrorPtr ) + : mContractID(aContractID), + mServiceManager( do_QueryInterface(aServiceManager) ), + mErrorPtr(aErrorPtr) + { + // nothing else to do + } + + virtual nsresult operator()( const nsIID&, void** ) const; + + virtual ~nsGetServiceByContractID() {}; + + private: + const char* mContractID; + nsCOMPtr mServiceManager; + nsresult* mErrorPtr; +}; + +inline +const nsGetServiceByContractID +do_GetService( const char* aContractID, nsresult* error = 0 ) +{ + return nsGetServiceByContractID(aContractID, 0, error); +} + +inline +const nsGetServiceByContractID +do_GetService( const char* aContractID, nsISupports* aServiceManager, nsresult* error = 0 ) +{ + return nsGetServiceByContractID(aContractID, aServiceManager, error); +} + +class NS_COM nsGetServiceFromCategory : public nsCOMPtr_helper +{ + public: + nsGetServiceFromCategory(const char* aCategory, const char* aEntry, + nsISupports* aServiceManager, + nsresult* aErrorPtr) + : mCategory(aCategory), + mEntry(aEntry), + mServiceManager( do_QueryInterface(aServiceManager) ), + mErrorPtr(aErrorPtr) + { + // nothing else to do + } + + virtual nsresult operator()( const nsIID&, void** ) const; + virtual ~nsGetServiceFromCategory() {}; + protected: + const char* mCategory; + const char* mEntry; + nsCOMPtr mServiceManager; + nsresult* mErrorPtr; +}; + +inline +const nsGetServiceFromCategory +do_GetServiceFromCategory( const char* category, const char* entry, + nsresult* error = 0) +{ + return nsGetServiceFromCategory(category, entry, 0, error); +} + +// type-safe shortcuts for calling |GetService| +template +inline +nsresult +CallGetService( const nsCID &aClass, + DestinationType** aDestination) +{ + NS_PRECONDITION(aDestination, "null parameter"); + + nsCOMPtr mgr; + nsresult rv = NS_GetServiceManager(getter_AddRefs(mgr)); + + if (NS_FAILED(rv)) + return rv; + + return mgr->GetService(aClass, + NS_GET_IID(DestinationType), + NS_REINTERPRET_CAST(void**, aDestination)); +} + +template +inline +nsresult +CallGetService( const char *aContractID, + DestinationType** aDestination) +{ + NS_PRECONDITION(aContractID, "null parameter"); + NS_PRECONDITION(aDestination, "null parameter"); + + nsCOMPtr mgr; + nsresult rv = NS_GetServiceManager(getter_AddRefs(mgr)); + + if (NS_FAILED(rv)) + return rv; + + return mgr->GetServiceByContractID(aContractID, + NS_GET_IID(DestinationType), + NS_REINTERPRET_CAST(void**, aDestination)); +} + +#endif diff --git a/xpcom/components/nsNativeComponentLoader.cpp b/xpcom/components/nsNativeComponentLoader.cpp index b0cd151db9e..ebd859ceae0 100644 --- a/xpcom/components/nsNativeComponentLoader.cpp +++ b/xpcom/components/nsNativeComponentLoader.cpp @@ -136,8 +136,8 @@ nsNativeComponentLoader::GetFactory(const nsIID & aCID, } /* Get service manager for factory */ - nsIServiceManager* serviceMgr = NULL; - rv = nsServiceManager::GetGlobalServiceManager(&serviceMgr); + nsCOMPtr serviceMgr; + rv = NS_GetServiceManager(getter_AddRefs(serviceMgr)); if (NS_FAILED(rv)) return rv; // XXX translate error code? @@ -457,8 +457,9 @@ nsNativeComponentLoader::SelfRegisterDll(nsDll *dll, // 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); + nsresult res; + nsCOMPtr serviceMgr; + res = NS_GetServiceManager(getter_AddRefs(serviceMgr)); if (NS_FAILED(res)) return res; if (dll->Load() == PR_FALSE) @@ -622,8 +623,9 @@ nsNativeComponentLoader::DumpLoadError(nsDll *dll, nsresult nsNativeComponentLoader::SelfUnregisterDll(nsDll *dll) { - nsIServiceManager* serviceMgr = NULL; - nsresult res = nsServiceManager::GetGlobalServiceManager(&serviceMgr); + nsresult res; + nsCOMPtr serviceMgr; + res = NS_GetServiceManager(getter_AddRefs(serviceMgr)); if (NS_FAILED(res)) return res; if (dll->Load() == PR_FALSE) @@ -681,8 +683,8 @@ nsNativeComponentLoader::AutoUnregisterComponent(PRInt32 when, do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv); if (NS_SUCCEEDED(rv)) { - nsIServiceManager *mgr; // NO COMPtr as we dont release the service manager - rv = nsServiceManager::GetGlobalServiceManager(&mgr); + nsCOMPtr mgr; + rv = NS_GetServiceManager(getter_AddRefs(mgr)); if (NS_SUCCEEDED(rv)) { (void) observerService->Notify(mgr, @@ -838,8 +840,8 @@ nsNativeComponentLoader::AutoRegisterComponent(PRInt32 when, do_GetService(NS_OBSERVERSERVICE_CONTRACTID, &rv); if (NS_SUCCEEDED(rv)) { - nsIServiceManager *mgr; // NO COMPtr as we dont release the service manager - rv = nsServiceManager::GetGlobalServiceManager(&mgr); + nsCOMPtr mgr; + rv = NS_GetServiceManager(getter_AddRefs(mgr)); if (NS_SUCCEEDED(rv)) { // this string can't come from a string bundle, because we don't have string @@ -867,8 +869,9 @@ nsNativeComponentLoader::AutoRegisterComponent(PRInt32 when, { // We loaded the old version of the dll and now we find that the // on-disk copy if newer. Try to unload the dll. - nsIServiceManager *serviceMgr = NULL; - nsServiceManager::GetGlobalServiceManager(&serviceMgr); + nsCOMPtr serviceMgr; + rv = NS_GetServiceManager(getter_AddRefs(serviceMgr)); + rv = nsFreeLibrary(dll, serviceMgr, when); if (NS_FAILED(rv)) { diff --git a/xpcom/components/nsServiceManagerObsolete.cpp b/xpcom/components/nsServiceManagerObsolete.cpp new file mode 100644 index 00000000000..8ec52b4b93f --- /dev/null +++ b/xpcom/components/nsServiceManagerObsolete.cpp @@ -0,0 +1,179 @@ +#include "nsIServiceManager.h" +#include "nsIServiceManagerObsolete.h" + +nsServiceManagerObsolete* gServiceManagerObsolete = nsnull; + +extern PRBool gXPCOMShuttingDown; + +// Global service manager interface (see nsIServiceManagerObsolete.h) + +nsresult +nsServiceManager::GetGlobalServiceManager(nsIServiceManager* *result) +{ + if (gXPCOMShuttingDown) + return NS_ERROR_UNEXPECTED; + + if (gServiceManagerObsolete) { + *result = (nsIServiceManager*)(void*)gServiceManagerObsolete; + return NS_OK; + } + + gServiceManagerObsolete = new nsServiceManagerObsolete(); + if (!gServiceManagerObsolete) + return NS_ERROR_OUT_OF_MEMORY; + + *result = (nsIServiceManager*)(void*)gServiceManagerObsolete; + return NS_OK; +} + +nsresult +nsServiceManager::ShutdownGlobalServiceManager(nsIServiceManager* *result) +{ + delete gServiceManagerObsolete; + gServiceManagerObsolete = nsnull; + return NS_OK; +} + +nsresult +nsServiceManager::GetService(const nsCID& aClass, const nsIID& aIID, + nsISupports* *result, + nsIShutdownListener* shutdownListener) +{ + nsCOMPtr mgr; + nsresult rv = NS_GetServiceManager(getter_AddRefs(mgr)); + if (NS_FAILED(rv)) return rv; + return mgr->GetService(aClass, aIID, (void**)result); +} + +nsresult +nsServiceManager::ReleaseService(const nsCID& aClass, nsISupports* service, + nsIShutdownListener* shutdownListener) +{ + NS_IF_RELEASE(service); + return NS_OK; +} + +nsresult +nsServiceManager::RegisterService(const nsCID& aClass, nsISupports* aService) +{ + nsCOMPtr mgr; + nsresult rv = NS_GetServiceManager(getter_AddRefs(mgr)); + if (NS_FAILED(rv)) return rv; + return NS_ERROR_NOT_IMPLEMENTED;//mgr->RegisterService(aClass, aService); +} + +nsresult +nsServiceManager::UnregisterService(const nsCID& aClass) +{ + nsCOMPtr mgr; + nsresult rv = NS_GetServiceManager(getter_AddRefs(mgr)); + if (NS_FAILED(rv)) return rv; + return NS_ERROR_NOT_IMPLEMENTED;//mgr->UnregisterService(aClass); +} + +//////////////////////////////////////////////////////////////////////////////// +// let's do it again, this time with ContractIDs... + +nsresult +nsServiceManager::GetService(const char* aContractID, const nsIID& aIID, + nsISupports* *result, + nsIShutdownListener* shutdownListener) +{ + nsCOMPtr mgr; + nsresult rv = NS_GetServiceManager(getter_AddRefs(mgr)); + if (NS_FAILED(rv)) return rv; + return mgr->GetServiceByContractID(aContractID, aIID, (void**)result); +} + +nsresult +nsServiceManager::ReleaseService(const char* aContractID, nsISupports* service, + nsIShutdownListener* shutdownListener) +{ + NS_RELEASE(service); + return NS_OK; +} + +nsresult +nsServiceManager::RegisterService(const char* aContractID, nsISupports* aService) +{ + nsCOMPtr mgr; + nsresult rv = NS_GetServiceManager(getter_AddRefs(mgr)); + if (NS_FAILED(rv)) return rv; + return NS_ERROR_NOT_IMPLEMENTED;//mgr->RegisterServiceByContractID(aContractID, aService); +} + +nsresult +nsServiceManager::UnregisterService(const char* aContractID) +{ + // Don't create the global service manager here because we might + // be shutting down, and releasing all the services in its + // destructor + if (gXPCOMShuttingDown) + return NS_OK; + nsCOMPtr mgr; + nsresult rv = NS_GetServiceManager(getter_AddRefs(mgr)); + if (NS_FAILED(rv)) return rv; + + return NS_ERROR_NOT_IMPLEMENTED;//mgr->UnregisterServiceByContractID(aContractID); +} + +//////////////////////////////////////////////////////////////////////////////// + +nsServiceManagerObsolete::nsServiceManagerObsolete() { + NS_INIT_ISUPPORTS(); + +} +nsServiceManagerObsolete::~nsServiceManagerObsolete() { +} + +NS_IMPL_ISUPPORTS1(nsServiceManagerObsolete, + nsIServiceManagerObsolete); + +NS_IMETHODIMP +nsServiceManagerObsolete::RegisterService(const nsCID& aClass, nsISupports* aService) { + return nsServiceManager::RegisterService(aClass, aService); +}; + +NS_IMETHODIMP +nsServiceManagerObsolete::UnregisterService(const nsCID& aClass){ + return nsServiceManager::UnregisterService(aClass); +}; + +NS_IMETHODIMP +nsServiceManagerObsolete::GetService(const nsCID& aClass, const nsIID& aIID, + nsISupports* *result, + nsIShutdownListener* shutdownListener){ + return nsServiceManager::GetService(aClass, aIID, result, shutdownListener); +}; + +NS_IMETHODIMP +nsServiceManagerObsolete::ReleaseService(const nsCID& aClass, nsISupports* service, + nsIShutdownListener* shutdownListener ){ + return nsServiceManager::ReleaseService(aClass, service, shutdownListener); +}; + +NS_IMETHODIMP +nsServiceManagerObsolete::RegisterService(const char* aContractID, nsISupports* aService){ + return nsServiceManager::RegisterService(aContractID, aService); +}; + +NS_IMETHODIMP +nsServiceManagerObsolete::UnregisterService(const char* aContractID){ + return nsServiceManager::UnregisterService(aContractID); +}; + +NS_IMETHODIMP +nsServiceManagerObsolete::GetService(const char* aContractID, const nsIID& aIID, + nsISupports* *result, + nsIShutdownListener* shutdownListener ){ + return nsServiceManager::GetService(aContractID, aIID, result, shutdownListener); +}; + +NS_IMETHODIMP +nsServiceManagerObsolete::ReleaseService(const char* aContractID, nsISupports* service, + nsIShutdownListener* shutdownListener ){ + return nsServiceManager::ReleaseService(aContractID, service, shutdownListener); +}; + + + diff --git a/xpcom/glue/nsServiceManagerUtils.h b/xpcom/glue/nsServiceManagerUtils.h new file mode 100644 index 00000000000..a3cd61a1cfd --- /dev/null +++ b/xpcom/glue/nsServiceManagerUtils.h @@ -0,0 +1,187 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: NPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Netscape 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/NPL/ + * + * 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 XPCOM + * + * The Initial Developer of the Original Code is Netscape Communications + * Corporation. + * Portions created by the Initial Developer are Copyright (C) 1998 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the NPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the NPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef nsIServiceManagerUtils_h__ +#define nsIServiceManagerUtils_h__ + +#include "nsIServiceManager.h" +#include "nsIServiceManagerObsolete.h" +#include "nsCOMPtr.h" + +//////////////////////////////////////////////////////////////////////////// +// Using servicemanager with COMPtrs +class NS_COM nsGetServiceByCID : public nsCOMPtr_helper +{ + public: + nsGetServiceByCID( const nsCID& aCID, nsISupports* aServiceManager, nsresult* aErrorPtr ) + : mCID(aCID), + mServiceManager( do_QueryInterface(aServiceManager) ), + mErrorPtr(aErrorPtr) + { + // nothing else to do + } + + virtual nsresult operator()( const nsIID&, void** ) const; + virtual ~nsGetServiceByCID() {}; + + private: + const nsCID& mCID; + nsCOMPtr mServiceManager; + nsresult* mErrorPtr; +}; + +inline +const nsGetServiceByCID +do_GetService( const nsCID& aCID, nsresult* error = 0 ) +{ + return nsGetServiceByCID(aCID, 0, error); +} + +inline +const nsGetServiceByCID +do_GetService( const nsCID& aCID, nsISupports* aServiceManager, nsresult* error = 0 ) +{ + return nsGetServiceByCID(aCID, aServiceManager, error); +} + +class NS_COM nsGetServiceByContractID : public nsCOMPtr_helper +{ + public: + nsGetServiceByContractID( const char* aContractID, nsISupports* aServiceManager, nsresult* aErrorPtr ) + : mContractID(aContractID), + mServiceManager( do_QueryInterface(aServiceManager) ), + mErrorPtr(aErrorPtr) + { + // nothing else to do + } + + virtual nsresult operator()( const nsIID&, void** ) const; + + virtual ~nsGetServiceByContractID() {}; + + private: + const char* mContractID; + nsCOMPtr mServiceManager; + nsresult* mErrorPtr; +}; + +inline +const nsGetServiceByContractID +do_GetService( const char* aContractID, nsresult* error = 0 ) +{ + return nsGetServiceByContractID(aContractID, 0, error); +} + +inline +const nsGetServiceByContractID +do_GetService( const char* aContractID, nsISupports* aServiceManager, nsresult* error = 0 ) +{ + return nsGetServiceByContractID(aContractID, aServiceManager, error); +} + +class NS_COM nsGetServiceFromCategory : public nsCOMPtr_helper +{ + public: + nsGetServiceFromCategory(const char* aCategory, const char* aEntry, + nsISupports* aServiceManager, + nsresult* aErrorPtr) + : mCategory(aCategory), + mEntry(aEntry), + mServiceManager( do_QueryInterface(aServiceManager) ), + mErrorPtr(aErrorPtr) + { + // nothing else to do + } + + virtual nsresult operator()( const nsIID&, void** ) const; + virtual ~nsGetServiceFromCategory() {}; + protected: + const char* mCategory; + const char* mEntry; + nsCOMPtr mServiceManager; + nsresult* mErrorPtr; +}; + +inline +const nsGetServiceFromCategory +do_GetServiceFromCategory( const char* category, const char* entry, + nsresult* error = 0) +{ + return nsGetServiceFromCategory(category, entry, 0, error); +} + +// type-safe shortcuts for calling |GetService| +template +inline +nsresult +CallGetService( const nsCID &aClass, + DestinationType** aDestination) +{ + NS_PRECONDITION(aDestination, "null parameter"); + + nsCOMPtr mgr; + nsresult rv = NS_GetServiceManager(getter_AddRefs(mgr)); + + if (NS_FAILED(rv)) + return rv; + + return mgr->GetService(aClass, + NS_GET_IID(DestinationType), + NS_REINTERPRET_CAST(void**, aDestination)); +} + +template +inline +nsresult +CallGetService( const char *aContractID, + DestinationType** aDestination) +{ + NS_PRECONDITION(aContractID, "null parameter"); + NS_PRECONDITION(aDestination, "null parameter"); + + nsCOMPtr mgr; + nsresult rv = NS_GetServiceManager(getter_AddRefs(mgr)); + + if (NS_FAILED(rv)) + return rv; + + return mgr->GetServiceByContractID(aContractID, + NS_GET_IID(DestinationType), + NS_REINTERPRET_CAST(void**, aDestination)); +} + +#endif diff --git a/xpcom/sample/nsTestSample.cpp b/xpcom/sample/nsTestSample.cpp index 5fed1fddf94..78be36285e4 100644 --- a/xpcom/sample/nsTestSample.cpp +++ b/xpcom/sample/nsTestSample.cpp @@ -54,7 +54,7 @@ main(void) nsresult rv; // Initialize XPCOM - rv = NS_InitXPCOM(nsnull, nsnull); + rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); if (NS_FAILED(rv)) { printf("ERROR: XPCOM intialization error [%x].\n", rv); diff --git a/xpcom/tests/TestBuffers.cpp b/xpcom/tests/TestBuffers.cpp index cb7e571b4c7..fb3cdccdbc3 100644 --- a/xpcom/tests/TestBuffers.cpp +++ b/xpcom/tests/TestBuffers.cpp @@ -359,7 +359,7 @@ main(int argc, char* argv[]) gVerbose = PR_TRUE; } - rv = NS_InitXPCOM(&servMgr, NULL); + rv = NS_InitXPCOM2(&servMgr, NULL, NULL); if (NS_FAILED(rv)) return rv; rv = TestWriteSegments(NS_OK); diff --git a/xpcom/tests/TestPipes.cpp b/xpcom/tests/TestPipes.cpp index 431f4978c0c..f32cfa5ddaf 100644 --- a/xpcom/tests/TestPipes.cpp +++ b/xpcom/tests/TestPipes.cpp @@ -610,7 +610,7 @@ main(int argc, char* argv[]) nsresult rv; nsIServiceManager* servMgr; - rv = NS_InitXPCOM(&servMgr, NULL); + rv = NS_InitXPCOM2(&servMgr, NULL, NULL); if (NS_FAILED(rv)) return rv; if (argc > 1 && nsCRT::strcmp(argv[1], "-trace") == 0) diff --git a/xpcom/tests/TestShutdown.cpp b/xpcom/tests/TestShutdown.cpp index c7c1f89a0d6..64ccd5c06ac 100644 --- a/xpcom/tests/TestShutdown.cpp +++ b/xpcom/tests/TestShutdown.cpp @@ -44,7 +44,7 @@ void main(int argc, char* argv[]) { nsresult rv; nsIServiceManager* servMgr; - rv = NS_InitXPCOM(&servMgr, NULL); + rv = NS_InitXPCOM2(&servMgr, NULL, NULL); NS_ASSERTION(NS_SUCCEEDED(rv), "NS_InitXPCOM failed"); // try loading a component and releasing it to see if it leaks diff --git a/xpcom/tests/TestThreads.cpp b/xpcom/tests/TestThreads.cpp index e4110339fc7..23ef342bb14 100644 --- a/xpcom/tests/TestThreads.cpp +++ b/xpcom/tests/TestThreads.cpp @@ -330,7 +330,7 @@ main(int argc, char** argv) int retval = 0; nsresult rv; - rv = NS_InitXPCOM(nsnull, nsnull); + rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); if (NS_FAILED(rv)) return -1; if (argc > 1 && !strcmp(argv[1], "-stress")) { diff --git a/xpcom/tests/nsIFileEnumerator.cpp b/xpcom/tests/nsIFileEnumerator.cpp index 6461b313093..1e589ad53f2 100644 --- a/xpcom/tests/nsIFileEnumerator.cpp +++ b/xpcom/tests/nsIFileEnumerator.cpp @@ -60,7 +60,7 @@ main(int argc, char* argv[]) nsresult rv; nsCOMPtr topDir; - rv = NS_InitXPCOM(nsnull, nsnull); + rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); if (NS_FAILED(rv)) return -1; nsComponentManager::AutoRegister(nsIComponentManager::NS_Startup, NULL); diff --git a/xpcom/tests/windows/TestHelloXPLoop.cpp b/xpcom/tests/windows/TestHelloXPLoop.cpp index e99859d1059..198c9018d4c 100644 --- a/xpcom/tests/windows/TestHelloXPLoop.cpp +++ b/xpcom/tests/windows/TestHelloXPLoop.cpp @@ -49,7 +49,7 @@ int WINAPI WinMain(HINSTANCE inst, HINSTANCE prevInstance, LPSTR lpszCmdLine, int retCode; nsresult rv; - rv = NS_InitXPCOM(NULL, NULL); + rv = NS_InitXPCOM2(NULL, NULL, NULL); { // Needed to scope all nsCOMPtr within XPCOM Init and Shutdown if(NS_FAILED(rv)) { diff --git a/xpcom/tools/registry/regExport.cpp b/xpcom/tools/registry/regExport.cpp index 4fa5285b86b..d3ba929a4c1 100644 --- a/xpcom/tools/registry/regExport.cpp +++ b/xpcom/tools/registry/regExport.cpp @@ -45,7 +45,6 @@ #include "prmem.h" #include "plstr.h" #include "nsMemory.h" -#include "nsIFileSpec.h" static void display( nsIRegistry *reg, nsRegistryKey root, const char *name ); static void displayValues( nsIRegistry *reg, nsRegistryKey root ); @@ -70,7 +69,7 @@ int main( int argc, char *argv[] ) { // Initialize XPCOM nsIServiceManager *servMgr = NULL; - rv = NS_InitXPCOM(&servMgr, NULL); + rv = NS_InitXPCOM2(&servMgr, NULL, NULL); if (NS_FAILED(rv)) { // Cannot initialize XPCOM diff --git a/xpcom/tools/registry/regxpcom.cpp b/xpcom/tools/registry/regxpcom.cpp index 1f920e680a8..667b72b97c4 100644 --- a/xpcom/tools/registry/regxpcom.cpp +++ b/xpcom/tools/registry/regxpcom.cpp @@ -183,7 +183,7 @@ int main(int argc, char *argv[]) #endif #endif - NS_InitXPCOM(NULL, NULL); + NS_InitXPCOM2(nsnull, nsnull, nsnull); /* With no arguments, RegFactory will autoregister */ if (argc <= 1) diff --git a/xpfe/bootstrap/nsAppRunner.cpp b/xpfe/bootstrap/nsAppRunner.cpp index 0b9849ef30b..4d6990ed3be 100644 --- a/xpfe/bootstrap/nsAppRunner.cpp +++ b/xpfe/bootstrap/nsAppRunner.cpp @@ -1598,7 +1598,7 @@ int main(int argc, char* argv[]) NS_TIMELINE_MARK("InitXPCom..."); - rv = NS_InitXPCOM(NULL, NULL); + rv = NS_InitXPCOM2(NULL, NULL, NULL); NS_ASSERTION( NS_SUCCEEDED(rv), "NS_InitXPCOM failed" ); NS_TIMELINE_MARK("...InitXPCOM done"); diff --git a/xpinstall/stub/xpistub.cpp b/xpinstall/stub/xpistub.cpp index cb114c73f9c..2ec11447ff4 100644 --- a/xpinstall/stub/xpistub.cpp +++ b/xpinstall/stub/xpistub.cpp @@ -108,7 +108,7 @@ PR_PUBLIC_API(nsresult) XPI_Init( if (binDir) { binDir->InitWithFSSpec(&aXPIStubDir); - rv = NS_InitXPCOM(&gServiceMgr, binDir); + rv = NS_InitXPCOM2(&gServiceMgr, binDir, nsnull); } else return NS_ERROR_FAILURE; @@ -128,11 +128,11 @@ PR_PUBLIC_API(nsresult) XPI_Init( nsCOMPtr file; NS_NewLocalFile(componentPath, PR_TRUE, getter_AddRefs(file)); - rv = NS_InitXPCOM(&gServiceMgr, file); + rv = NS_InitXPCOM2(&gServiceMgr, file, nsnull); #elif defined(XP_UNIX) - rv = NS_InitXPCOM(&gServiceMgr, nsnull); + rv = NS_InitXPCOM2(&gServiceMgr, nsnull, nsnull); char cwd[1024]; char compDirPath[1024]; @@ -147,7 +147,7 @@ PR_PUBLIC_API(nsresult) XPI_Init( #else - rv = NS_InitXPCOM(&gServiceMgr, NULL); + rv = NS_InitXPCOM2(&gServiceMgr, NULL, NULL); #endif