1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/xpcom/components/nsComponentManager.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,349 @@ 1.4 +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef nsComponentManager_h__ 1.10 +#define nsComponentManager_h__ 1.11 + 1.12 +#include "nsXPCOM.h" 1.13 + 1.14 +#include "xpcom-private.h" 1.15 +#include "nsIComponentManager.h" 1.16 +#include "nsIComponentRegistrar.h" 1.17 +#include "nsIMemoryReporter.h" 1.18 +#include "nsIServiceManager.h" 1.19 +#include "nsIFile.h" 1.20 +#include "mozilla/MemoryReporting.h" 1.21 +#include "mozilla/Module.h" 1.22 +#include "mozilla/ModuleLoader.h" 1.23 +#include "mozilla/Mutex.h" 1.24 +#include "nsXULAppAPI.h" 1.25 +#include "nsNativeComponentLoader.h" 1.26 +#include "nsIFactory.h" 1.27 +#include "nsIInterfaceRequestor.h" 1.28 +#include "nsIInterfaceRequestorUtils.h" 1.29 +#include "pldhash.h" 1.30 +#include "prtime.h" 1.31 +#include "nsCOMPtr.h" 1.32 +#include "nsAutoPtr.h" 1.33 +#include "nsWeakReference.h" 1.34 +#include "plarena.h" 1.35 +#include "nsCOMArray.h" 1.36 +#include "nsDataHashtable.h" 1.37 +#include "nsInterfaceHashtable.h" 1.38 +#include "nsClassHashtable.h" 1.39 +#include "nsTArray.h" 1.40 + 1.41 +#include "mozilla/Omnijar.h" 1.42 +#include "mozilla/Attributes.h" 1.43 + 1.44 +struct nsFactoryEntry; 1.45 +class nsIServiceManager; 1.46 +struct PRThread; 1.47 + 1.48 +#define NS_COMPONENTMANAGER_CID \ 1.49 +{ /* 91775d60-d5dc-11d2-92fb-00e09805570f */ \ 1.50 + 0x91775d60, \ 1.51 + 0xd5dc, \ 1.52 + 0x11d2, \ 1.53 + {0x92, 0xfb, 0x00, 0xe0, 0x98, 0x05, 0x57, 0x0f} \ 1.54 +} 1.55 + 1.56 +/* keys for registry use */ 1.57 +extern const char xpcomKeyName[]; 1.58 +extern const char xpcomComponentsKeyName[]; 1.59 +extern const char lastModValueName[]; 1.60 +extern const char fileSizeValueName[]; 1.61 +extern const char nativeComponentType[]; 1.62 +extern const char staticComponentType[]; 1.63 + 1.64 +#ifdef DEBUG 1.65 +#define XPCOM_CHECK_PENDING_CIDS 1.66 +#endif 1.67 +//////////////////////////////////////////////////////////////////////////////// 1.68 + 1.69 +extern const mozilla::Module kXPCOMModule; 1.70 + 1.71 +/** 1.72 + * This is a wrapper around mozilla::Mutex which provides runtime 1.73 + * checking for a deadlock where the same thread tries to lock a mutex while 1.74 + * it is already locked. This checking is present in both debug and release 1.75 + * builds. 1.76 + */ 1.77 +class SafeMutex 1.78 +{ 1.79 +public: 1.80 + SafeMutex(const char* name) 1.81 + : mMutex(name) 1.82 + , mOwnerThread(nullptr) 1.83 + { } 1.84 + ~SafeMutex() 1.85 + { } 1.86 + 1.87 + void Lock() 1.88 + { 1.89 + AssertNotCurrentThreadOwns(); 1.90 + mMutex.Lock(); 1.91 + MOZ_ASSERT(mOwnerThread == nullptr); 1.92 + mOwnerThread = PR_GetCurrentThread(); 1.93 + } 1.94 + 1.95 + void Unlock() 1.96 + { 1.97 + MOZ_ASSERT(mOwnerThread == PR_GetCurrentThread()); 1.98 + mOwnerThread = nullptr; 1.99 + mMutex.Unlock(); 1.100 + } 1.101 + 1.102 + void AssertCurrentThreadOwns() const 1.103 + { 1.104 + // This method is a debug-only check 1.105 + MOZ_ASSERT(mOwnerThread == PR_GetCurrentThread()); 1.106 + } 1.107 + 1.108 + MOZ_NEVER_INLINE void AssertNotCurrentThreadOwns() const 1.109 + { 1.110 + // This method is a release-mode check 1.111 + if (PR_GetCurrentThread() == mOwnerThread) { 1.112 + MOZ_CRASH(); 1.113 + } 1.114 + } 1.115 + 1.116 +private: 1.117 + mozilla::Mutex mMutex; 1.118 + volatile PRThread* mOwnerThread; 1.119 +}; 1.120 + 1.121 +typedef mozilla::BaseAutoLock<SafeMutex> SafeMutexAutoLock; 1.122 +typedef mozilla::BaseAutoUnlock<SafeMutex> SafeMutexAutoUnlock; 1.123 + 1.124 +class nsComponentManagerImpl MOZ_FINAL 1.125 + : public nsIComponentManager 1.126 + , public nsIServiceManager 1.127 + , public nsSupportsWeakReference 1.128 + , public nsIComponentRegistrar 1.129 + , public nsIInterfaceRequestor 1.130 + , public nsIMemoryReporter 1.131 +{ 1.132 +public: 1.133 + NS_DECL_THREADSAFE_ISUPPORTS 1.134 + NS_DECL_NSIINTERFACEREQUESTOR 1.135 + NS_DECL_NSICOMPONENTMANAGER 1.136 + NS_DECL_NSICOMPONENTREGISTRAR 1.137 + NS_DECL_NSIMEMORYREPORTER 1.138 + 1.139 + static nsresult Create(nsISupports* aOuter, REFNSIID aIID, void** aResult); 1.140 + 1.141 + nsresult RegistryLocationForFile(nsIFile* aFile, 1.142 + nsCString& aResult); 1.143 + nsresult FileForRegistryLocation(const nsCString &aLocation, 1.144 + nsIFile **aSpec); 1.145 + 1.146 + NS_DECL_NSISERVICEMANAGER 1.147 + 1.148 + // nsComponentManagerImpl methods: 1.149 + nsComponentManagerImpl(); 1.150 + 1.151 + static nsComponentManagerImpl* gComponentManager; 1.152 + nsresult Init(); 1.153 + 1.154 + nsresult Shutdown(void); 1.155 + 1.156 + nsresult FreeServices(); 1.157 + 1.158 + already_AddRefed<mozilla::ModuleLoader> LoaderForExtension(const nsACString& aExt); 1.159 + nsInterfaceHashtable<nsCStringHashKey, mozilla::ModuleLoader> mLoaderMap; 1.160 + 1.161 + already_AddRefed<nsIFactory> FindFactory(const nsCID& aClass); 1.162 + already_AddRefed<nsIFactory> FindFactory(const char *contractID, 1.163 + uint32_t aContractIDLen); 1.164 + 1.165 + already_AddRefed<nsIFactory> LoadFactory(nsFactoryEntry *aEntry); 1.166 + 1.167 + nsFactoryEntry *GetFactoryEntry(const char *aContractID, 1.168 + uint32_t aContractIDLen); 1.169 + nsFactoryEntry *GetFactoryEntry(const nsCID &aClass); 1.170 + 1.171 + nsDataHashtable<nsIDHashKey, nsFactoryEntry*> mFactories; 1.172 + nsDataHashtable<nsCStringHashKey, nsFactoryEntry*> mContractIDs; 1.173 + 1.174 + SafeMutex mLock; 1.175 + 1.176 + static void InitializeStaticModules(); 1.177 + static void InitializeModuleLocations(); 1.178 + 1.179 + struct ComponentLocation 1.180 + { 1.181 + NSLocationType type; 1.182 + mozilla::FileLocation location; 1.183 + }; 1.184 + 1.185 + class ComponentLocationComparator 1.186 + { 1.187 + public: 1.188 + bool Equals(const ComponentLocation& a, const ComponentLocation& b) const 1.189 + { 1.190 + return (a.type == b.type && a.location.Equals(b.location)); 1.191 + } 1.192 + }; 1.193 + 1.194 + static nsTArray<const mozilla::Module*>* sStaticModules; 1.195 + static nsTArray<ComponentLocation>* sModuleLocations; 1.196 + 1.197 + nsNativeModuleLoader mNativeModuleLoader; 1.198 + 1.199 + class KnownModule 1.200 + { 1.201 + public: 1.202 + /** 1.203 + * Static or binary module. 1.204 + */ 1.205 + KnownModule(const mozilla::Module* aModule, mozilla::FileLocation &aFile) 1.206 + : mModule(aModule) 1.207 + , mFile(aFile) 1.208 + , mLoaded(false) 1.209 + , mFailed(false) 1.210 + { } 1.211 + 1.212 + KnownModule(const mozilla::Module* aModule) 1.213 + : mModule(aModule) 1.214 + , mLoaded(false) 1.215 + , mFailed(false) 1.216 + { } 1.217 + 1.218 + KnownModule(mozilla::FileLocation &aFile) 1.219 + : mModule(nullptr) 1.220 + , mFile(aFile) 1.221 + , mLoader(nullptr) 1.222 + , mLoaded(false) 1.223 + , mFailed(false) 1.224 + { } 1.225 + 1.226 + ~KnownModule() 1.227 + { 1.228 + if (mLoaded && mModule->unloadProc) 1.229 + mModule->unloadProc(); 1.230 + } 1.231 + 1.232 + bool EnsureLoader(); 1.233 + bool Load(); 1.234 + 1.235 + const mozilla::Module* Module() const 1.236 + { 1.237 + return mModule; 1.238 + } 1.239 + 1.240 + /** 1.241 + * For error logging, get a description of this module, either the 1.242 + * file path, or <static module>. 1.243 + */ 1.244 + nsCString Description() const; 1.245 + 1.246 + private: 1.247 + const mozilla::Module* mModule; 1.248 + mozilla::FileLocation mFile; 1.249 + nsCOMPtr<mozilla::ModuleLoader> mLoader; 1.250 + bool mLoaded; 1.251 + bool mFailed; 1.252 + }; 1.253 + 1.254 + // The KnownModule is kept alive by these members, it is 1.255 + // referenced by pointer from the factory entries. 1.256 + nsTArray< nsAutoPtr<KnownModule> > mKnownStaticModules; 1.257 + // The key is the URI string of the module 1.258 + nsClassHashtable<nsCStringHashKey, KnownModule> mKnownModules; 1.259 + 1.260 + // Mutex not held 1.261 + void RegisterModule(const mozilla::Module* aModule, 1.262 + mozilla::FileLocation* aFile); 1.263 + 1.264 + 1.265 + // Mutex held 1.266 + void RegisterCIDEntryLocked(const mozilla::Module::CIDEntry* aEntry, 1.267 + KnownModule* aModule); 1.268 + void RegisterContractIDLocked(const mozilla::Module::ContractIDEntry* aEntry); 1.269 + 1.270 + // Mutex not held 1.271 + void RegisterManifest(NSLocationType aType, mozilla::FileLocation &aFile, 1.272 + bool aChromeOnly); 1.273 + 1.274 + struct ManifestProcessingContext 1.275 + { 1.276 + ManifestProcessingContext(NSLocationType aType, mozilla::FileLocation &aFile, bool aChromeOnly) 1.277 + : mType(aType) 1.278 + , mFile(aFile) 1.279 + , mChromeOnly(aChromeOnly) 1.280 + { } 1.281 + 1.282 + ~ManifestProcessingContext() { } 1.283 + 1.284 + NSLocationType mType; 1.285 + mozilla::FileLocation mFile; 1.286 + bool mChromeOnly; 1.287 + }; 1.288 + 1.289 + void ManifestManifest(ManifestProcessingContext& cx, int lineno, char *const * argv); 1.290 + void ManifestBinaryComponent(ManifestProcessingContext& cx, int lineno, char *const * argv); 1.291 + void ManifestXPT(ManifestProcessingContext& cx, int lineno, char *const * argv); 1.292 + void ManifestComponent(ManifestProcessingContext& cx, int lineno, char *const * argv); 1.293 + void ManifestContract(ManifestProcessingContext& cx, int lineno, char* const * argv); 1.294 + void ManifestCategory(ManifestProcessingContext& cx, int lineno, char* const * argv); 1.295 + 1.296 + void RereadChromeManifests(bool aChromeOnly = true); 1.297 + 1.298 + // Shutdown 1.299 + enum { 1.300 + NOT_INITIALIZED, 1.301 + NORMAL, 1.302 + SHUTDOWN_IN_PROGRESS, 1.303 + SHUTDOWN_COMPLETE 1.304 + } mStatus; 1.305 + 1.306 + PLArenaPool mArena; 1.307 + 1.308 + struct PendingServiceInfo { 1.309 + const nsCID* cid; 1.310 + PRThread* thread; 1.311 + }; 1.312 + 1.313 + inline PendingServiceInfo* AddPendingService(const nsCID& aServiceCID, 1.314 + PRThread* aThread); 1.315 + inline void RemovePendingService(const nsCID& aServiceCID); 1.316 + inline PRThread* GetPendingServiceThread(const nsCID& aServiceCID) const; 1.317 + 1.318 + nsTArray<PendingServiceInfo> mPendingServices; 1.319 + 1.320 + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf); 1.321 + 1.322 +private: 1.323 + ~nsComponentManagerImpl(); 1.324 +}; 1.325 + 1.326 + 1.327 +#define NS_MAX_FILENAME_LEN 1024 1.328 + 1.329 +#define NS_ERROR_IS_DIR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XPCOM, 24) 1.330 + 1.331 +struct nsFactoryEntry 1.332 +{ 1.333 + nsFactoryEntry(const mozilla::Module::CIDEntry* entry, 1.334 + nsComponentManagerImpl::KnownModule* module); 1.335 + 1.336 + // nsIComponentRegistrar.registerFactory support 1.337 + nsFactoryEntry(const nsCID& aClass, nsIFactory* factory); 1.338 + 1.339 + ~nsFactoryEntry(); 1.340 + 1.341 + already_AddRefed<nsIFactory> GetFactory(); 1.342 + 1.343 + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf); 1.344 + 1.345 + const mozilla::Module::CIDEntry* mCIDEntry; 1.346 + nsComponentManagerImpl::KnownModule* mModule; 1.347 + 1.348 + nsCOMPtr<nsIFactory> mFactory; 1.349 + nsCOMPtr<nsISupports> mServiceObject; 1.350 +}; 1.351 + 1.352 +#endif // nsComponentManager_h__