LCOV - code coverage report
Current view: top level - xpcom/components - nsComponentManager.h (source / functions) Hit Total Coverage
Test: output.info Lines: 36 49 73.5 %
Date: 2017-07-14 16:53:18 Functions: 11 16 68.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef nsComponentManager_h__
       8             : #define nsComponentManager_h__
       9             : 
      10             : #include "nsXPCOM.h"
      11             : 
      12             : #include "xpcom-private.h"
      13             : #include "nsIComponentManager.h"
      14             : #include "nsIComponentRegistrar.h"
      15             : #include "nsIMemoryReporter.h"
      16             : #include "nsIServiceManager.h"
      17             : #include "nsIFile.h"
      18             : #include "mozilla/ArenaAllocator.h"
      19             : #include "mozilla/Atomics.h"
      20             : #include "mozilla/MemoryReporting.h"
      21             : #include "mozilla/Module.h"
      22             : #include "mozilla/ModuleLoader.h"
      23             : #include "mozilla/Mutex.h"
      24             : #include "nsXULAppAPI.h"
      25             : #include "nsIFactory.h"
      26             : #include "nsIInterfaceRequestor.h"
      27             : #include "nsIInterfaceRequestorUtils.h"
      28             : #include "PLDHashTable.h"
      29             : #include "prtime.h"
      30             : #include "nsCOMPtr.h"
      31             : #include "nsAutoPtr.h"
      32             : #include "nsWeakReference.h"
      33             : #include "nsCOMArray.h"
      34             : #include "nsDataHashtable.h"
      35             : #include "nsInterfaceHashtable.h"
      36             : #include "nsClassHashtable.h"
      37             : #include "nsTArray.h"
      38             : 
      39             : #include "mozilla/Omnijar.h"
      40             : #include "mozilla/Attributes.h"
      41             : 
      42             : struct nsFactoryEntry;
      43             : class nsIServiceManager;
      44             : struct PRThread;
      45             : 
      46             : #define NS_COMPONENTMANAGER_CID                      \
      47             : { /* 91775d60-d5dc-11d2-92fb-00e09805570f */         \
      48             :     0x91775d60,                                      \
      49             :     0xd5dc,                                          \
      50             :     0x11d2,                                          \
      51             :     {0x92, 0xfb, 0x00, 0xe0, 0x98, 0x05, 0x57, 0x0f} \
      52             : }
      53             : 
      54             : /* keys for registry use */
      55             : extern const char xpcomKeyName[];
      56             : extern const char xpcomComponentsKeyName[];
      57             : extern const char lastModValueName[];
      58             : extern const char fileSizeValueName[];
      59             : extern const char nativeComponentType[];
      60             : extern const char staticComponentType[];
      61             : 
      62             : #ifdef DEBUG
      63             : #define XPCOM_CHECK_PENDING_CIDS
      64             : #endif
      65             : ////////////////////////////////////////////////////////////////////////////////
      66             : 
      67             : extern const mozilla::Module kXPCOMModule;
      68             : 
      69             : /**
      70             :  * This is a wrapper around mozilla::Mutex which provides runtime
      71             :  * checking for a deadlock where the same thread tries to lock a mutex while
      72             :  * it is already locked. This checking is present in both debug and release
      73             :  * builds.
      74             :  */
      75             : class SafeMutex
      76             : {
      77             : public:
      78           3 :   explicit SafeMutex(const char* aName)
      79           3 :     : mMutex(aName)
      80           3 :     , mOwnerThread(nullptr)
      81             :   {
      82           3 :   }
      83             : 
      84           0 :   ~SafeMutex() {}
      85             : 
      86       11008 :   void Lock()
      87             :   {
      88       11008 :     AssertNotCurrentThreadOwns();
      89       11008 :     mMutex.Lock();
      90       11008 :     MOZ_ASSERT(mOwnerThread == nullptr);
      91       11008 :     mOwnerThread = PR_GetCurrentThread();
      92       11008 :   }
      93             : 
      94       11008 :   void Unlock()
      95             :   {
      96       11008 :     MOZ_ASSERT(mOwnerThread == PR_GetCurrentThread());
      97       11008 :     mOwnerThread = nullptr;
      98       11008 :     mMutex.Unlock();
      99       11008 :   }
     100             : 
     101        3513 :   void AssertCurrentThreadOwns() const
     102             :   {
     103             :     // This method is a debug-only check
     104        3513 :     MOZ_ASSERT(mOwnerThread == PR_GetCurrentThread());
     105        3513 :   }
     106             : 
     107       13881 :   MOZ_NEVER_INLINE void AssertNotCurrentThreadOwns() const
     108             :   {
     109             :     // This method is a release-mode check
     110       13881 :     if (PR_GetCurrentThread() == mOwnerThread) {
     111           0 :       MOZ_CRASH();
     112             :     }
     113       13881 :   }
     114             : 
     115             : private:
     116             :   mozilla::Mutex mMutex;
     117             :   mozilla::Atomic<PRThread*, mozilla::Relaxed> mOwnerThread;
     118             : };
     119             : 
     120             : typedef mozilla::BaseAutoLock<SafeMutex> SafeMutexAutoLock;
     121             : typedef mozilla::BaseAutoUnlock<SafeMutex> SafeMutexAutoUnlock;
     122             : 
     123             : class nsComponentManagerImpl final
     124             :   : public nsIComponentManager
     125             :   , public nsIServiceManager
     126             :   , public nsSupportsWeakReference
     127             :   , public nsIComponentRegistrar
     128             :   , public nsIInterfaceRequestor
     129             :   , public nsIMemoryReporter
     130             : {
     131             : public:
     132             :   NS_DECL_THREADSAFE_ISUPPORTS
     133             :   NS_DECL_NSIINTERFACEREQUESTOR
     134             :   NS_DECL_NSICOMPONENTMANAGER
     135             :   NS_DECL_NSICOMPONENTREGISTRAR
     136             :   NS_DECL_NSIMEMORYREPORTER
     137             : 
     138             :   static nsresult Create(nsISupports* aOuter, REFNSIID aIID, void** aResult);
     139             : 
     140             :   nsresult RegistryLocationForFile(nsIFile* aFile,
     141             :                                    nsCString& aResult);
     142             :   nsresult FileForRegistryLocation(const nsCString& aLocation,
     143             :                                    nsIFile** aSpec);
     144             : 
     145             :   NS_DECL_NSISERVICEMANAGER
     146             : 
     147             :   // nsComponentManagerImpl methods:
     148             :   nsComponentManagerImpl();
     149             : 
     150             :   static nsComponentManagerImpl* gComponentManager;
     151             :   nsresult Init();
     152             : 
     153             :   nsresult Shutdown(void);
     154             : 
     155             :   nsresult FreeServices();
     156             : 
     157             :   already_AddRefed<mozilla::ModuleLoader> LoaderForExtension(const nsACString& aExt);
     158             :   nsInterfaceHashtable<nsCStringHashKey, mozilla::ModuleLoader> mLoaderMap;
     159             : 
     160             :   already_AddRefed<nsIFactory> FindFactory(const nsCID& aClass);
     161             :   already_AddRefed<nsIFactory> FindFactory(const char* aContractID,
     162             :                                            uint32_t aContractIDLen);
     163             : 
     164             :   already_AddRefed<nsIFactory> LoadFactory(nsFactoryEntry* aEntry);
     165             : 
     166             :   nsFactoryEntry* GetFactoryEntry(const char* aContractID,
     167             :                                   uint32_t aContractIDLen);
     168             :   nsFactoryEntry* GetFactoryEntry(const nsCID& aClass);
     169             : 
     170             :   nsDataHashtable<nsIDHashKey, nsFactoryEntry*> mFactories;
     171             :   nsDataHashtable<nsCStringHashKey, nsFactoryEntry*> mContractIDs;
     172             : 
     173             :   SafeMutex mLock;
     174             : 
     175             :   static void InitializeStaticModules();
     176             :   static void InitializeModuleLocations();
     177             : 
     178          23 :   struct ComponentLocation
     179             :   {
     180             :     NSLocationType type;
     181             :     mozilla::FileLocation location;
     182             :   };
     183             : 
     184             :   class ComponentLocationComparator
     185             :   {
     186             :   public:
     187           0 :     bool Equals(const ComponentLocation& aA, const ComponentLocation& aB) const
     188             :     {
     189           0 :       return (aA.type == aB.type && aA.location.Equals(aB.location));
     190             :     }
     191             :   };
     192             : 
     193             :   static nsTArray<const mozilla::Module*>* sStaticModules;
     194             :   static nsTArray<ComponentLocation>* sModuleLocations;
     195             : 
     196             :   class KnownModule
     197             :   {
     198             :   public:
     199             :     /**
     200             :      * Static or binary module.
     201             :      */
     202           0 :     KnownModule(const mozilla::Module* aModule, mozilla::FileLocation& aFile)
     203           0 :       : mModule(aModule)
     204             :       , mFile(aFile)
     205             :       , mLoaded(false)
     206           0 :       , mFailed(false)
     207             :     {
     208           0 :     }
     209             : 
     210         207 :     explicit KnownModule(const mozilla::Module* aModule)
     211         207 :       : mModule(aModule)
     212             :       , mLoaded(false)
     213         207 :       , mFailed(false)
     214             :     {
     215         207 :     }
     216             : 
     217         310 :     explicit KnownModule(mozilla::FileLocation& aFile)
     218         310 :       : mModule(nullptr)
     219             :       , mFile(aFile)
     220             :       , mLoader(nullptr)
     221             :       , mLoaded(false)
     222         310 :       , mFailed(false)
     223             :     {
     224         310 :     }
     225             : 
     226           0 :     ~KnownModule()
     227           0 :     {
     228           0 :       if (mLoaded && mModule->unloadProc) {
     229           0 :         mModule->unloadProc();
     230             :       }
     231           0 :     }
     232             : 
     233             :     bool EnsureLoader();
     234             :     bool Load();
     235             : 
     236         566 :     const mozilla::Module* Module() const { return mModule; }
     237             : 
     238             :     /**
     239             :      * For error logging, get a description of this module, either the
     240             :      * file path, or <static module>.
     241             :      */
     242             :     nsCString Description() const;
     243             : 
     244             :   private:
     245             :     const mozilla::Module* mModule;
     246             :     mozilla::FileLocation mFile;
     247             :     nsCOMPtr<mozilla::ModuleLoader> mLoader;
     248             :     bool mLoaded;
     249             :     bool mFailed;
     250             :   };
     251             : 
     252             :   // The KnownModule is kept alive by these members, it is
     253             :   // referenced by pointer from the factory entries.
     254             :   nsTArray<nsAutoPtr<KnownModule>> mKnownStaticModules;
     255             :   // The key is the URI string of the module
     256             :   nsClassHashtable<nsCStringHashKey, KnownModule> mKnownModules;
     257             : 
     258             :   // Mutex not held
     259             :   void RegisterModule(const mozilla::Module* aModule,
     260             :                       mozilla::FileLocation* aFile);
     261             : 
     262             : 
     263             :   // Mutex held
     264             :   void RegisterCIDEntryLocked(const mozilla::Module::CIDEntry* aEntry,
     265             :                               KnownModule* aModule);
     266             :   void RegisterContractIDLocked(const mozilla::Module::ContractIDEntry* aEntry);
     267             : 
     268             :   // Mutex not held
     269             :   void RegisterManifest(NSLocationType aType, mozilla::FileLocation& aFile,
     270             :                         bool aChromeOnly);
     271             : 
     272             :   struct ManifestProcessingContext
     273             :   {
     274         311 :     ManifestProcessingContext(NSLocationType aType,
     275             :                               mozilla::FileLocation& aFile, bool aChromeOnly)
     276         311 :       : mType(aType)
     277             :       , mFile(aFile)
     278         311 :       , mChromeOnly(aChromeOnly)
     279             :     {
     280         311 :     }
     281             : 
     282         311 :     ~ManifestProcessingContext() {}
     283             : 
     284             :     NSLocationType mType;
     285             :     mozilla::FileLocation mFile;
     286             :     bool mChromeOnly;
     287             :   };
     288             : 
     289             :   void ManifestManifest(ManifestProcessingContext& aCx, int aLineNo,
     290             :                         char* const* aArgv);
     291             :   void ManifestBinaryComponent(ManifestProcessingContext& aCx, int aLineNo,
     292             :                                char* const* aArgv);
     293             :   void ManifestXPT(ManifestProcessingContext& aCx, int aLineNo,
     294             :                    char* const* aArgv);
     295             :   void ManifestComponent(ManifestProcessingContext& aCx, int aLineNo,
     296             :                          char* const* aArgv);
     297             :   void ManifestContract(ManifestProcessingContext& aCx, int aLineNo,
     298             :                         char* const* aArgv);
     299             :   void ManifestCategory(ManifestProcessingContext& aCx, int aLineNo,
     300             :                         char* const* aArgv);
     301             : 
     302             :   void RereadChromeManifests(bool aChromeOnly = true);
     303             : 
     304             :   // Shutdown
     305             :   enum
     306             :   {
     307             :     NOT_INITIALIZED,
     308             :     NORMAL,
     309             :     SHUTDOWN_IN_PROGRESS,
     310             :     SHUTDOWN_COMPLETE
     311             :   } mStatus;
     312             : 
     313             :   mozilla::ArenaAllocator<1024*8, 8> mArena;
     314             : 
     315             :   struct PendingServiceInfo
     316             :   {
     317             :     const nsCID* cid;
     318             :     PRThread* thread;
     319             :   };
     320             : 
     321             :   inline PendingServiceInfo* AddPendingService(const nsCID& aServiceCID,
     322             :                                                PRThread* aThread);
     323             :   inline void RemovePendingService(const nsCID& aServiceCID);
     324             :   inline PRThread* GetPendingServiceThread(const nsCID& aServiceCID) const;
     325             : 
     326             :   nsTArray<PendingServiceInfo> mPendingServices;
     327             : 
     328             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
     329             : 
     330             : private:
     331             :   ~nsComponentManagerImpl();
     332             : };
     333             : 
     334             : 
     335             : #define NS_MAX_FILENAME_LEN     1024
     336             : 
     337             : #define NS_ERROR_IS_DIR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XPCOM, 24)
     338             : 
     339             : struct nsFactoryEntry
     340             : {
     341             :   nsFactoryEntry(const mozilla::Module::CIDEntry* aEntry,
     342             :                  nsComponentManagerImpl::KnownModule* aModule);
     343             : 
     344             :   // nsIComponentRegistrar.registerFactory support
     345             :   nsFactoryEntry(const nsCID& aClass, nsIFactory* aFactory);
     346             : 
     347             :   ~nsFactoryEntry();
     348             : 
     349             :   already_AddRefed<nsIFactory> GetFactory();
     350             : 
     351             :   size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
     352             : 
     353             :   const mozilla::Module::CIDEntry* mCIDEntry;
     354             :   nsComponentManagerImpl::KnownModule* mModule;
     355             : 
     356             :   nsCOMPtr<nsIFactory>   mFactory;
     357             :   nsCOMPtr<nsISupports>  mServiceObject;
     358             : };
     359             : 
     360             : #endif // nsComponentManager_h__

Generated by: LCOV version 1.13