summaryrefslogtreecommitdiffstats
path: root/mailnews/base/util/Services.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'mailnews/base/util/Services.cpp')
-rw-r--r--mailnews/base/util/Services.cpp106
1 files changed, 106 insertions, 0 deletions
diff --git a/mailnews/base/util/Services.cpp b/mailnews/base/util/Services.cpp
new file mode 100644
index 000000000..a10d44aa3
--- /dev/null
+++ b/mailnews/base/util/Services.cpp
@@ -0,0 +1,106 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * 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/. */
+
+#include "mozilla/mailnews/Services.h"
+
+#include "nsIObserverService.h"
+#include "nsIObserver.h"
+#include "nsServiceManagerUtils.h"
+
+// All of the includes for the services we initiate here
+#include "mozINewMailNotificationService.h"
+#include "nsIAbManager.h"
+#include "nsIImapService.h"
+#include "nsIImportService.h"
+#include "nsIMimeConverter.h"
+#include "nsIMsgAccountManager.h"
+#include "nsIMsgComposeService.h"
+#include "nsIMsgCopyService.h"
+#include "nsIMsgDatabase.h"
+#include "nsIMsgFilterService.h"
+#include "nsIMsgFolderNotificationService.h"
+#include "nsIMsgHeaderParser.h"
+#include "nsIMsgMailSession.h"
+#include "nsIMsgTagService.h"
+#include "nsINntpService.h"
+#include "nsIPop3Service.h"
+#include "nsISmtpService.h"
+
+namespace mozilla {
+namespace services {
+
+namespace {
+class ShutdownObserver final : public nsIObserver
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIOBSERVER
+
+ static void EnsureInitialized();
+private:
+ ~ShutdownObserver() {}
+
+ void ShutdownServices();
+ static ShutdownObserver *sShutdownObserver;
+ static bool sShuttingDown;
+};
+
+bool ShutdownObserver::sShuttingDown = false;
+ShutdownObserver *ShutdownObserver::sShutdownObserver = nullptr;
+}
+
+#define MOZ_SERVICE(NAME, TYPE, CONTRACT_ID) \
+ static TYPE *g##NAME = nullptr; \
+ already_AddRefed<TYPE> Get##NAME() \
+ { \
+ ShutdownObserver::EnsureInitialized(); \
+ if (!g##NAME) \
+ { \
+ nsCOMPtr<TYPE> os = do_GetService(CONTRACT_ID); \
+ os.forget(&g##NAME); \
+ MOZ_ASSERT(g##NAME, "This service is unexpectedly missing."); \
+ } \
+ nsCOMPtr<TYPE> ret = g##NAME; \
+ return ret.forget(); \
+ }
+#include "mozilla/mailnews/ServiceList.h"
+#undef MOZ_SERVICE
+
+NS_IMPL_ISUPPORTS(ShutdownObserver, nsIObserver)
+
+NS_IMETHODIMP ShutdownObserver::Observe(nsISupports *aSubject,
+ const char *aTopic, const char16_t *aData)
+{
+ if (!strcmp(aTopic, "xpcom-shutdown-threads"))
+ ShutdownServices();
+ return NS_OK;
+}
+
+void ShutdownObserver::EnsureInitialized()
+{
+ MOZ_ASSERT(!sShuttingDown, "It is illegal to use this code after shutdown!");
+ if (!sShutdownObserver)
+ {
+ sShutdownObserver = new ShutdownObserver;
+ sShutdownObserver->AddRef();
+ nsCOMPtr<nsIObserverService> obs(mozilla::services::GetObserverService());
+ MOZ_ASSERT(obs, "This should never be null");
+ obs->AddObserver(sShutdownObserver, "xpcom-shutdown-threads", false);
+ }
+}
+
+void ShutdownObserver::ShutdownServices()
+{
+ sShuttingDown = true;
+ MOZ_ASSERT(sShutdownObserver, "Shutting down twice?");
+ sShutdownObserver->Release();
+ sShutdownObserver = nullptr;
+#define MOZ_SERVICE(NAME, TYPE, CONTRACT_ID) NS_IF_RELEASE(g##NAME);
+#include "mozilla/mailnews/ServiceList.h"
+#undef MOZ_SERVICE
+}
+
+} // namespace services
+} // namespace mozilla