Bumping manifests a=b2g-bump
[gecko.git] / xpcom / components / nsComponentManager.h
blobff51441fb4ceb0b2000abbb83575a3b2eb1356cd
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__
9 #include "nsXPCOM.h"
11 #include "xpcom-private.h"
12 #include "nsIComponentManager.h"
13 #include "nsIComponentRegistrar.h"
14 #include "nsIMemoryReporter.h"
15 #include "nsIServiceManager.h"
16 #include "nsIFile.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"
26 #include "pldhash.h"
27 #include "prtime.h"
28 #include "nsCOMPtr.h"
29 #include "nsAutoPtr.h"
30 #include "nsWeakReference.h"
31 #include "plarena.h"
32 #include "nsCOMArray.h"
33 #include "nsDataHashtable.h"
34 #include "nsInterfaceHashtable.h"
35 #include "nsClassHashtable.h"
36 #include "nsTArray.h"
38 #include "mozilla/Omnijar.h"
39 #include "mozilla/Attributes.h"
41 #ifdef MOZ_B2G_LOADER
42 #include "mozilla/FileLocation.h"
43 #endif
45 struct nsFactoryEntry;
46 class nsIServiceManager;
47 struct PRThread;
49 #define NS_COMPONENTMANAGER_CID \
50 { /* 91775d60-d5dc-11d2-92fb-00e09805570f */ \
51 0x91775d60, \
52 0xd5dc, \
53 0x11d2, \
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[];
65 #ifdef DEBUG
66 #define XPCOM_CHECK_PENDING_CIDS
67 #endif
68 ////////////////////////////////////////////////////////////////////////////////
70 extern const mozilla::Module kXPCOMModule;
72 /**
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
76 * builds.
78 class SafeMutex
80 public:
81 explicit SafeMutex(const char* aName)
82 : mMutex(aName)
83 , mOwnerThread(nullptr)
87 ~SafeMutex() {}
89 void Lock()
91 AssertNotCurrentThreadOwns();
92 mMutex.Lock();
93 MOZ_ASSERT(mOwnerThread == nullptr);
94 mOwnerThread = PR_GetCurrentThread();
97 void Unlock()
99 MOZ_ASSERT(mOwnerThread == PR_GetCurrentThread());
100 mOwnerThread = nullptr;
101 mMutex.Unlock();
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) {
114 MOZ_CRASH();
118 private:
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
134 public:
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,
144 nsCString& aResult);
145 nsresult FileForRegistryLocation(const nsCString& aLocation,
146 nsIFile** aSpec);
148 NS_DECL_NSISERVICEMANAGER
150 // nsComponentManagerImpl methods:
151 nsComponentManagerImpl();
153 static nsComponentManagerImpl* gComponentManager;
154 nsresult Init();
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;
176 SafeMutex mLock;
178 static void InitializeStaticModules();
179 static void InitializeModuleLocations();
181 struct ComponentLocation
183 NSLocationType type;
184 mozilla::FileLocation location;
187 class ComponentLocationComparator
189 public:
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;
201 class KnownModule
203 public:
205 * Static or binary module.
207 KnownModule(const mozilla::Module* aModule, mozilla::FileLocation& aFile)
208 : mModule(aModule)
209 , mFile(aFile)
210 , mLoaded(false)
211 , mFailed(false)
215 explicit KnownModule(const mozilla::Module* aModule)
216 : mModule(aModule)
217 , mLoaded(false)
218 , mFailed(false)
222 explicit KnownModule(mozilla::FileLocation& aFile)
223 : mModule(nullptr)
224 , mFile(aFile)
225 , mLoader(nullptr)
226 , mLoaded(false)
227 , mFailed(false)
231 ~KnownModule()
233 if (mLoaded && mModule->unloadProc) {
234 mModule->unloadProc();
238 bool EnsureLoader();
239 bool Load();
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;
249 private:
250 const mozilla::Module* mModule;
251 mozilla::FileLocation mFile;
252 nsCOMPtr<mozilla::ModuleLoader> mLoader;
253 bool mLoaded;
254 bool mFailed;
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;
263 // Mutex not held
264 void RegisterModule(const mozilla::Module* aModule,
265 mozilla::FileLocation* aFile);
268 // Mutex held
269 void RegisterCIDEntryLocked(const mozilla::Module::CIDEntry* aEntry,
270 KnownModule* aModule);
271 void RegisterContractIDLocked(const mozilla::Module::ContractIDEntry* aEntry);
273 // Mutex not held
274 void RegisterManifest(NSLocationType aType, mozilla::FileLocation& aFile,
275 bool aChromeOnly);
277 struct ManifestProcessingContext
279 ManifestProcessingContext(NSLocationType aType,
280 mozilla::FileLocation& aFile, bool aChromeOnly)
281 : mType(aType)
282 , mFile(aFile)
283 , mChromeOnly(aChromeOnly)
287 ~ManifestProcessingContext() {}
289 NSLocationType mType;
290 mozilla::FileLocation mFile;
291 bool mChromeOnly;
294 void ManifestManifest(ManifestProcessingContext& aCx, int aLineNo,
295 char* const* aArgv);
296 void ManifestBinaryComponent(ManifestProcessingContext& aCx, int aLineNo,
297 char* const* aArgv);
298 void ManifestXPT(ManifestProcessingContext& aCx, int aLineNo,
299 char* const* aArgv);
300 void ManifestComponent(ManifestProcessingContext& aCx, int aLineNo,
301 char* const* aArgv);
302 void ManifestContract(ManifestProcessingContext& aCx, int aLineNo,
303 char* const* aArgv);
304 void ManifestCategory(ManifestProcessingContext& aCx, int aLineNo,
305 char* const* aArgv);
307 void RereadChromeManifests(bool aChromeOnly = true);
309 // Shutdown
310 enum
312 NOT_INITIALIZED,
313 NORMAL,
314 SHUTDOWN_IN_PROGRESS,
315 SHUTDOWN_COMPLETE
316 } mStatus;
318 PLArenaPool mArena;
320 struct PendingServiceInfo
322 const nsCID* cid;
323 PRThread* thread;
326 inline PendingServiceInfo* AddPendingService(const nsCID& aServiceCID,
327 PRThread* aThread);
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);
339 #endif
341 #ifdef MOZ_B2G_LOADER
342 // Parsing functions of directives of manifest for XPT only parsing.
343 struct XPTOnlyManifestProcessingContext
345 XPTOnlyManifestProcessingContext(mozilla::FileLocation& aFile)
346 : mFile(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);
358 #endif
360 private:
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);
377 ~nsFactoryEntry();
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__