summaryrefslogtreecommitdiffstats
path: root/xpcom/build/Services.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--xpcom/build/Services.py170
1 files changed, 170 insertions, 0 deletions
diff --git a/xpcom/build/Services.py b/xpcom/build/Services.py
new file mode 100644
index 0000000000..43f010d05b
--- /dev/null
+++ b/xpcom/build/Services.py
@@ -0,0 +1,170 @@
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# NOTE: Although this generates headers and code for C++, using Services.h
+# is deprecated in favour of Components.h.
+
+
+services = []
+
+
+def service(name, iface, contractid):
+ """Define a convenient service getter"""
+ services.append((name, iface, contractid))
+
+
+# The `name` parameter is derived from the `iface` by removing the `nsI`
+# prefix. (This often matches the `contractid`, but not always.)
+service("ChromeRegistry", "nsIChromeRegistry", "@mozilla.org/chrome/chrome-registry;1")
+service("IOService", "nsIIOService", "@mozilla.org/network/io-service;1")
+service("ObserverService", "nsIObserverService", "@mozilla.org/observer-service;1")
+service("PermissionManager", "nsIPermissionManager", "@mozilla.org/permissionmanager;1")
+service(
+ "AsyncShutdownService",
+ "nsIAsyncShutdownService",
+ "@mozilla.org/async-shutdown-service;1",
+)
+
+# The definition file needs access to the definitions of the particular
+# interfaces. If you add a new interface here, make sure the necessary includes
+# are also listed in the following code snippet.
+CPP_INCLUDES = """
+#include "mozilla/Likely.h"
+#include "mozilla/Services.h"
+#include "mozIThirdPartyUtil.h"
+#include "nsComponentManager.h"
+#include "nsIObserverService.h"
+#include "nsNetCID.h"
+#include "nsObserverService.h"
+#include "nsXPCOMPrivate.h"
+#include "nsIIOService.h"
+#include "nsIDirectoryService.h"
+#include "nsIChromeRegistry.h"
+#include "nsIStringBundle.h"
+#include "nsIToolkitChromeRegistry.h"
+#include "IHistory.h"
+#include "nsIXPConnect.h"
+#include "nsIPermissionManager.h"
+#include "nsIPrefService.h"
+#include "nsIServiceWorkerManager.h"
+#include "nsICacheStorageService.h"
+#include "nsIStreamTransportService.h"
+#include "nsISocketTransportService.h"
+#include "nsIURIClassifier.h"
+#include "nsIHttpActivityObserver.h"
+#include "nsIAsyncShutdown.h"
+#include "nsIUUIDGenerator.h"
+#include "nsIGfxInfo.h"
+#include "nsIURIFixup.h"
+#include "nsIBits.h"
+#include "nsIXULRuntime.h"
+"""
+
+
+#####
+# Codegen Logic
+#
+# The following code consumes the data listed above to generate the files
+# Services.h, and Services.cpp which provide access to these service getters in
+# C++ code.
+
+
+def services_h(output):
+ output.write(
+ """\
+/* THIS FILE IS GENERATED BY Services.py - DO NOT EDIT */
+
+#ifndef mozilla_Services_h
+#define mozilla_Services_h
+
+#include "nscore.h"
+#include "nsCOMPtr.h"
+"""
+ )
+
+ for name, iface, contractid in services:
+ # Write out a forward declaration for the type in question
+ segs = iface.split("::")
+ for namespace in segs[:-1]:
+ output.write("namespace %s {\n" % namespace)
+ output.write("class %s;\n" % segs[-1])
+ for namespace in reversed(segs[:-1]):
+ output.write("} // namespace %s\n" % namespace)
+
+ # Write out the C-style function signature, and the C++ wrapper
+ output.write(
+ """
+#ifdef MOZILLA_INTERNAL_API
+namespace mozilla {
+namespace services {
+/**
+ * Fetch a cached instance of the %(name)s.
+ * This function will return nullptr during XPCOM shutdown.
+ * Prefer using static components to this method.
+ * WARNING: This method is _not_ threadsafe!
+ */
+already_AddRefed<%(type)s> Get%(name)s();
+} // namespace services
+} // namespace mozilla
+#endif // defined(MOZILLA_INTERNAL_API)
+"""
+ % {
+ "name": name,
+ "type": iface,
+ }
+ )
+
+ output.write("#endif // !defined(mozilla_Services_h)\n")
+
+
+def services_cpp(output):
+ output.write(
+ """\
+/* THIS FILE IS GENERATED BY Services.py - DO NOT EDIT */
+"""
+ )
+ output.write(CPP_INCLUDES)
+
+ for name, iface, contractid in services:
+ output.write(
+ """
+static %(type)s* g%(name)s = nullptr;
+
+namespace mozilla {
+namespace services {
+already_AddRefed<%(type)s> Get%(name)s()
+{
+ if (MOZ_UNLIKELY(gXPCOMShuttingDown)) {
+ return nullptr;
+ }
+ if (!g%(name)s) {
+ nsCOMPtr<%(type)s> os = do_GetService("%(contractid)s");
+ os.swap(g%(name)s);
+ }
+ return do_AddRef(g%(name)s);
+}
+}
+}
+"""
+ % {
+ "name": name,
+ "type": iface,
+ "contractid": contractid,
+ }
+ )
+
+ output.write(
+ """
+/**
+ * Clears service cache, sets gXPCOMShuttingDown
+ */
+void
+mozilla::services::Shutdown()
+{
+ gXPCOMShuttingDown = true;
+"""
+ )
+ for name, iface, contractid in services:
+ output.write(" NS_IF_RELEASE(g%s);\n" % name)
+ output.write("}\n")