diff options
Diffstat (limited to 'mailnews/base/util/Services.cpp')
-rw-r--r-- | mailnews/base/util/Services.cpp | 106 |
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 |