1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsComponentManager_h__
7 #define nsComponentManager_h__
11 #include "xpcom-private.h"
12 #include "nsIComponentManager.h"
13 #include "nsIComponentRegistrar.h"
14 #include "nsIMemoryReporter.h"
15 #include "nsIServiceManager.h"
17 #include "mozilla/MemoryReporting.h"
18 #include "mozilla/Module.h"
19 #include "mozilla/ModuleLoader.h"
20 #include "mozilla/Mutex.h"
21 #include "nsXULAppAPI.h"
22 #include "nsNativeModuleLoader.h"
23 #include "nsIFactory.h"
24 #include "nsIInterfaceRequestor.h"
25 #include "nsIInterfaceRequestorUtils.h"
29 #include "nsAutoPtr.h"
30 #include "nsWeakReference.h"
32 #include "nsCOMArray.h"
33 #include "nsDataHashtable.h"
34 #include "nsInterfaceHashtable.h"
35 #include "nsClassHashtable.h"
38 #include "mozilla/Omnijar.h"
39 #include "mozilla/Attributes.h"
42 #include "mozilla/FileLocation.h"
45 struct nsFactoryEntry
;
46 class nsIServiceManager
;
49 #define NS_COMPONENTMANAGER_CID \
50 { /* 91775d60-d5dc-11d2-92fb-00e09805570f */ \
54 {0x92, 0xfb, 0x00, 0xe0, 0x98, 0x05, 0x57, 0x0f} \
57 /* keys for registry use */
58 extern const char xpcomKeyName
[];
59 extern const char xpcomComponentsKeyName
[];
60 extern const char lastModValueName
[];
61 extern const char fileSizeValueName
[];
62 extern const char nativeComponentType
[];
63 extern const char staticComponentType
[];
66 #define XPCOM_CHECK_PENDING_CIDS
68 ////////////////////////////////////////////////////////////////////////////////
70 extern const mozilla::Module kXPCOMModule
;
73 * This is a wrapper around mozilla::Mutex which provides runtime
74 * checking for a deadlock where the same thread tries to lock a mutex while
75 * it is already locked. This checking is present in both debug and release
81 explicit SafeMutex(const char* aName
)
83 , mOwnerThread(nullptr)
91 AssertNotCurrentThreadOwns();
93 MOZ_ASSERT(mOwnerThread
== nullptr);
94 mOwnerThread
= PR_GetCurrentThread();
99 MOZ_ASSERT(mOwnerThread
== PR_GetCurrentThread());
100 mOwnerThread
= nullptr;
104 void AssertCurrentThreadOwns() const
106 // This method is a debug-only check
107 MOZ_ASSERT(mOwnerThread
== PR_GetCurrentThread());
110 MOZ_NEVER_INLINE
void AssertNotCurrentThreadOwns() const
112 // This method is a release-mode check
113 if (PR_GetCurrentThread() == mOwnerThread
) {
119 mozilla::Mutex mMutex
;
120 volatile PRThread
* mOwnerThread
;
123 typedef mozilla::BaseAutoLock
<SafeMutex
> SafeMutexAutoLock
;
124 typedef mozilla::BaseAutoUnlock
<SafeMutex
> SafeMutexAutoUnlock
;
126 class nsComponentManagerImpl MOZ_FINAL
127 : public nsIComponentManager
128 , public nsIServiceManager
129 , public nsSupportsWeakReference
130 , public nsIComponentRegistrar
131 , public nsIInterfaceRequestor
132 , public nsIMemoryReporter
135 NS_DECL_THREADSAFE_ISUPPORTS
136 NS_DECL_NSIINTERFACEREQUESTOR
137 NS_DECL_NSICOMPONENTMANAGER
138 NS_DECL_NSICOMPONENTREGISTRAR
139 NS_DECL_NSIMEMORYREPORTER
141 static nsresult
Create(nsISupports
* aOuter
, REFNSIID aIID
, void** aResult
);
143 nsresult
RegistryLocationForFile(nsIFile
* aFile
,
145 nsresult
FileForRegistryLocation(const nsCString
& aLocation
,
148 NS_DECL_NSISERVICEMANAGER
150 // nsComponentManagerImpl methods:
151 nsComponentManagerImpl();
153 static nsComponentManagerImpl
* gComponentManager
;
156 nsresult
Shutdown(void);
158 nsresult
FreeServices();
160 already_AddRefed
<mozilla::ModuleLoader
> LoaderForExtension(const nsACString
& aExt
);
161 nsInterfaceHashtable
<nsCStringHashKey
, mozilla::ModuleLoader
> mLoaderMap
;
163 already_AddRefed
<nsIFactory
> FindFactory(const nsCID
& aClass
);
164 already_AddRefed
<nsIFactory
> FindFactory(const char* aContractID
,
165 uint32_t aContractIDLen
);
167 already_AddRefed
<nsIFactory
> LoadFactory(nsFactoryEntry
* aEntry
);
169 nsFactoryEntry
* GetFactoryEntry(const char* aContractID
,
170 uint32_t aContractIDLen
);
171 nsFactoryEntry
* GetFactoryEntry(const nsCID
& aClass
);
173 nsDataHashtable
<nsIDHashKey
, nsFactoryEntry
*> mFactories
;
174 nsDataHashtable
<nsCStringHashKey
, nsFactoryEntry
*> mContractIDs
;
178 static void InitializeStaticModules();
179 static void InitializeModuleLocations();
181 struct ComponentLocation
184 mozilla::FileLocation location
;
187 class ComponentLocationComparator
190 bool Equals(const ComponentLocation
& aA
, const ComponentLocation
& aB
) const
192 return (aA
.type
== aB
.type
&& aA
.location
.Equals(aB
.location
));
196 static nsTArray
<const mozilla::Module
*>* sStaticModules
;
197 static nsTArray
<ComponentLocation
>* sModuleLocations
;
199 nsNativeModuleLoader mNativeModuleLoader
;
205 * Static or binary module.
207 KnownModule(const mozilla::Module
* aModule
, mozilla::FileLocation
& aFile
)
215 explicit KnownModule(const mozilla::Module
* aModule
)
222 explicit KnownModule(mozilla::FileLocation
& aFile
)
233 if (mLoaded
&& mModule
->unloadProc
) {
234 mModule
->unloadProc();
241 const mozilla::Module
* Module() const { return mModule
; }
244 * For error logging, get a description of this module, either the
245 * file path, or <static module>.
247 nsCString
Description() const;
250 const mozilla::Module
* mModule
;
251 mozilla::FileLocation mFile
;
252 nsCOMPtr
<mozilla::ModuleLoader
> mLoader
;
257 // The KnownModule is kept alive by these members, it is
258 // referenced by pointer from the factory entries.
259 nsTArray
<nsAutoPtr
<KnownModule
>> mKnownStaticModules
;
260 // The key is the URI string of the module
261 nsClassHashtable
<nsCStringHashKey
, KnownModule
> mKnownModules
;
264 void RegisterModule(const mozilla::Module
* aModule
,
265 mozilla::FileLocation
* aFile
);
269 void RegisterCIDEntryLocked(const mozilla::Module::CIDEntry
* aEntry
,
270 KnownModule
* aModule
);
271 void RegisterContractIDLocked(const mozilla::Module::ContractIDEntry
* aEntry
);
274 void RegisterManifest(NSLocationType aType
, mozilla::FileLocation
& aFile
,
277 struct ManifestProcessingContext
279 ManifestProcessingContext(NSLocationType aType
,
280 mozilla::FileLocation
& aFile
, bool aChromeOnly
)
283 , mChromeOnly(aChromeOnly
)
287 ~ManifestProcessingContext() {}
289 NSLocationType mType
;
290 mozilla::FileLocation mFile
;
294 void ManifestManifest(ManifestProcessingContext
& aCx
, int aLineNo
,
296 void ManifestBinaryComponent(ManifestProcessingContext
& aCx
, int aLineNo
,
298 void ManifestXPT(ManifestProcessingContext
& aCx
, int aLineNo
,
300 void ManifestComponent(ManifestProcessingContext
& aCx
, int aLineNo
,
302 void ManifestContract(ManifestProcessingContext
& aCx
, int aLineNo
,
304 void ManifestCategory(ManifestProcessingContext
& aCx
, int aLineNo
,
307 void RereadChromeManifests(bool aChromeOnly
= true);
314 SHUTDOWN_IN_PROGRESS
,
320 struct PendingServiceInfo
326 inline PendingServiceInfo
* AddPendingService(const nsCID
& aServiceCID
,
328 inline void RemovePendingService(const nsCID
& aServiceCID
);
329 inline PRThread
* GetPendingServiceThread(const nsCID
& aServiceCID
) const;
331 nsTArray
<PendingServiceInfo
> mPendingServices
;
333 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf
);
335 #ifdef MOZ_B2G_LOADER
336 // Preload XPT interface info for B2G loader.
337 // This function is called before XPCOM has been initialized.
338 static void PreloadXPT(nsIFile
* aFile
);
341 #ifdef MOZ_B2G_LOADER
342 // Parsing functions of directives of manifest for XPT only parsing.
343 struct XPTOnlyManifestProcessingContext
345 XPTOnlyManifestProcessingContext(mozilla::FileLocation
& aFile
)
350 ~XPTOnlyManifestProcessingContext() {}
352 mozilla::FileLocation mFile
;
354 static void XPTOnlyManifestManifest(XPTOnlyManifestProcessingContext
& aCx
,
355 int aLineNo
, char* const* aArgv
);
356 static void XPTOnlyManifestXPT(XPTOnlyManifestProcessingContext
& aCx
,
357 int aLineNo
, char* const* aArgv
);
361 ~nsComponentManagerImpl();
365 #define NS_MAX_FILENAME_LEN 1024
367 #define NS_ERROR_IS_DIR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XPCOM, 24)
369 struct nsFactoryEntry
371 nsFactoryEntry(const mozilla::Module::CIDEntry
* aEntry
,
372 nsComponentManagerImpl::KnownModule
* aModule
);
374 // nsIComponentRegistrar.registerFactory support
375 nsFactoryEntry(const nsCID
& aClass
, nsIFactory
* aFactory
);
379 already_AddRefed
<nsIFactory
> GetFactory();
381 size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf
);
383 const mozilla::Module::CIDEntry
* mCIDEntry
;
384 nsComponentManagerImpl::KnownModule
* mModule
;
386 nsCOMPtr
<nsIFactory
> mFactory
;
387 nsCOMPtr
<nsISupports
> mServiceObject
;
390 #endif // nsComponentManager_h__