1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
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
|