xpcom/components/nsComponentManager.h

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

     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 "nsNativeComponentLoader.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 struct nsFactoryEntry;
    42 class nsIServiceManager;
    43 struct PRThread;
    45 #define NS_COMPONENTMANAGER_CID                      \
    46 { /* 91775d60-d5dc-11d2-92fb-00e09805570f */         \
    47     0x91775d60,                                      \
    48     0xd5dc,                                          \
    49     0x11d2,                                          \
    50     {0x92, 0xfb, 0x00, 0xe0, 0x98, 0x05, 0x57, 0x0f} \
    51 }
    53 /* keys for registry use */
    54 extern const char xpcomKeyName[];
    55 extern const char xpcomComponentsKeyName[];
    56 extern const char lastModValueName[];
    57 extern const char fileSizeValueName[];
    58 extern const char nativeComponentType[];
    59 extern const char staticComponentType[];
    61 #ifdef DEBUG
    62 #define XPCOM_CHECK_PENDING_CIDS
    63 #endif
    64 ////////////////////////////////////////////////////////////////////////////////
    66 extern const mozilla::Module kXPCOMModule;
    68 /**
    69  * This is a wrapper around mozilla::Mutex which provides runtime
    70  * checking for a deadlock where the same thread tries to lock a mutex while
    71  * it is already locked. This checking is present in both debug and release
    72  * builds.
    73  */
    74 class SafeMutex
    75 {
    76 public:
    77     SafeMutex(const char* name)
    78         : mMutex(name)
    79         , mOwnerThread(nullptr)
    80     { }
    81     ~SafeMutex()
    82     { }
    84     void Lock()
    85     {
    86         AssertNotCurrentThreadOwns();
    87         mMutex.Lock();
    88         MOZ_ASSERT(mOwnerThread == nullptr);
    89         mOwnerThread = PR_GetCurrentThread();
    90     }
    92     void Unlock()
    93     {
    94         MOZ_ASSERT(mOwnerThread == PR_GetCurrentThread());
    95         mOwnerThread = nullptr;
    96         mMutex.Unlock();
    97     }
    99     void AssertCurrentThreadOwns() const
   100     {
   101         // This method is a debug-only check
   102         MOZ_ASSERT(mOwnerThread == PR_GetCurrentThread());
   103     }
   105     MOZ_NEVER_INLINE void AssertNotCurrentThreadOwns() const
   106     {
   107         // This method is a release-mode check
   108         if (PR_GetCurrentThread() == mOwnerThread) {
   109             MOZ_CRASH();
   110         }
   111     }
   113 private:
   114     mozilla::Mutex mMutex;
   115     volatile PRThread* mOwnerThread;
   116 };
   118 typedef mozilla::BaseAutoLock<SafeMutex> SafeMutexAutoLock;
   119 typedef mozilla::BaseAutoUnlock<SafeMutex> SafeMutexAutoUnlock;
   121 class nsComponentManagerImpl MOZ_FINAL
   122     : public nsIComponentManager
   123     , public nsIServiceManager
   124     , public nsSupportsWeakReference
   125     , public nsIComponentRegistrar
   126     , public nsIInterfaceRequestor
   127     , public nsIMemoryReporter
   128 {
   129 public:
   130     NS_DECL_THREADSAFE_ISUPPORTS
   131     NS_DECL_NSIINTERFACEREQUESTOR
   132     NS_DECL_NSICOMPONENTMANAGER
   133     NS_DECL_NSICOMPONENTREGISTRAR
   134     NS_DECL_NSIMEMORYREPORTER
   136     static nsresult Create(nsISupports* aOuter, REFNSIID aIID, void** aResult);
   138     nsresult RegistryLocationForFile(nsIFile* aFile,
   139                                      nsCString& aResult);
   140     nsresult FileForRegistryLocation(const nsCString &aLocation,
   141                                      nsIFile **aSpec);
   143     NS_DECL_NSISERVICEMANAGER
   145     // nsComponentManagerImpl methods:
   146     nsComponentManagerImpl();
   148     static nsComponentManagerImpl* gComponentManager;
   149     nsresult Init();
   151     nsresult Shutdown(void);
   153     nsresult FreeServices();
   155     already_AddRefed<mozilla::ModuleLoader> LoaderForExtension(const nsACString& aExt);
   156     nsInterfaceHashtable<nsCStringHashKey, mozilla::ModuleLoader> mLoaderMap;
   158     already_AddRefed<nsIFactory> FindFactory(const nsCID& aClass);
   159     already_AddRefed<nsIFactory> FindFactory(const char *contractID,
   160                                              uint32_t aContractIDLen);
   162     already_AddRefed<nsIFactory> LoadFactory(nsFactoryEntry *aEntry);
   164     nsFactoryEntry *GetFactoryEntry(const char *aContractID,
   165                                     uint32_t aContractIDLen);
   166     nsFactoryEntry *GetFactoryEntry(const nsCID &aClass);
   168     nsDataHashtable<nsIDHashKey, nsFactoryEntry*> mFactories;
   169     nsDataHashtable<nsCStringHashKey, nsFactoryEntry*> mContractIDs;
   171     SafeMutex mLock;
   173     static void InitializeStaticModules();
   174     static void InitializeModuleLocations();
   176     struct ComponentLocation
   177     {
   178         NSLocationType type;
   179         mozilla::FileLocation location;
   180     };
   182     class ComponentLocationComparator
   183     {
   184     public:
   185       bool Equals(const ComponentLocation& a, const ComponentLocation& b) const
   186       {
   187         return (a.type == b.type && a.location.Equals(b.location));
   188       }
   189     };
   191     static nsTArray<const mozilla::Module*>* sStaticModules;
   192     static nsTArray<ComponentLocation>* sModuleLocations;
   194     nsNativeModuleLoader mNativeModuleLoader;
   196     class KnownModule
   197     {
   198     public:
   199         /**
   200          * Static or binary module.
   201          */
   202         KnownModule(const mozilla::Module* aModule, mozilla::FileLocation &aFile)
   203             : mModule(aModule)
   204             , mFile(aFile)
   205             , mLoaded(false)
   206             , mFailed(false)
   207         { }
   209         KnownModule(const mozilla::Module* aModule)
   210             : mModule(aModule)
   211             , mLoaded(false)
   212             , mFailed(false)
   213         { }
   215         KnownModule(mozilla::FileLocation &aFile)
   216             : mModule(nullptr)
   217             , mFile(aFile)
   218             , mLoader(nullptr)
   219             , mLoaded(false)
   220             , mFailed(false)
   221         { }
   223         ~KnownModule()
   224         {
   225             if (mLoaded && mModule->unloadProc)
   226                 mModule->unloadProc();
   227         }
   229         bool EnsureLoader();
   230         bool Load();
   232         const mozilla::Module* Module() const
   233         {
   234             return mModule;
   235         }
   237         /**
   238          * For error logging, get a description of this module, either the
   239          * file path, or <static module>.
   240          */
   241         nsCString Description() const;
   243     private:
   244         const mozilla::Module* mModule;
   245         mozilla::FileLocation mFile;
   246         nsCOMPtr<mozilla::ModuleLoader> mLoader;
   247         bool mLoaded;
   248         bool mFailed;
   249     };
   251     // The KnownModule is kept alive by these members, it is
   252     // referenced by pointer from the factory entries.
   253     nsTArray< nsAutoPtr<KnownModule> > mKnownStaticModules;
   254     // The key is the URI string of the module
   255     nsClassHashtable<nsCStringHashKey, KnownModule> mKnownModules;
   257     // Mutex not held
   258     void RegisterModule(const mozilla::Module* aModule,
   259                         mozilla::FileLocation* aFile);
   262     // Mutex held
   263     void RegisterCIDEntryLocked(const mozilla::Module::CIDEntry* aEntry,
   264                           KnownModule* aModule);
   265     void RegisterContractIDLocked(const mozilla::Module::ContractIDEntry* aEntry);
   267     // Mutex not held
   268     void RegisterManifest(NSLocationType aType, mozilla::FileLocation &aFile,
   269                           bool aChromeOnly);
   271     struct ManifestProcessingContext
   272     {
   273         ManifestProcessingContext(NSLocationType aType, mozilla::FileLocation &aFile, bool aChromeOnly)
   274             : mType(aType)
   275             , mFile(aFile)
   276             , mChromeOnly(aChromeOnly)
   277         { }
   279         ~ManifestProcessingContext() { }
   281         NSLocationType mType;
   282         mozilla::FileLocation mFile;
   283         bool mChromeOnly;
   284     };
   286     void ManifestManifest(ManifestProcessingContext& cx, int lineno, char *const * argv);
   287     void ManifestBinaryComponent(ManifestProcessingContext& cx, int lineno, char *const * argv);
   288     void ManifestXPT(ManifestProcessingContext& cx, int lineno, char *const * argv);
   289     void ManifestComponent(ManifestProcessingContext& cx, int lineno, char *const * argv);
   290     void ManifestContract(ManifestProcessingContext& cx, int lineno, char* const * argv);
   291     void ManifestCategory(ManifestProcessingContext& cx, int lineno, char* const * argv);
   293     void RereadChromeManifests(bool aChromeOnly = true);
   295     // Shutdown
   296     enum {
   297         NOT_INITIALIZED,
   298         NORMAL,
   299         SHUTDOWN_IN_PROGRESS,
   300         SHUTDOWN_COMPLETE
   301     } mStatus;
   303     PLArenaPool   mArena;
   305     struct PendingServiceInfo {
   306       const nsCID* cid;
   307       PRThread* thread;
   308     };
   310     inline PendingServiceInfo* AddPendingService(const nsCID& aServiceCID,
   311                                                  PRThread* aThread);
   312     inline void RemovePendingService(const nsCID& aServiceCID);
   313     inline PRThread* GetPendingServiceThread(const nsCID& aServiceCID) const;
   315     nsTArray<PendingServiceInfo> mPendingServices;
   317     size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
   319 private:
   320     ~nsComponentManagerImpl();
   321 };
   324 #define NS_MAX_FILENAME_LEN     1024
   326 #define NS_ERROR_IS_DIR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XPCOM, 24)
   328 struct nsFactoryEntry
   329 {
   330     nsFactoryEntry(const mozilla::Module::CIDEntry* entry,
   331                    nsComponentManagerImpl::KnownModule* module);
   333     // nsIComponentRegistrar.registerFactory support
   334     nsFactoryEntry(const nsCID& aClass, nsIFactory* factory);
   336     ~nsFactoryEntry();
   338     already_AddRefed<nsIFactory> GetFactory();
   340     size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
   342     const mozilla::Module::CIDEntry* mCIDEntry;
   343     nsComponentManagerImpl::KnownModule* mModule;
   345     nsCOMPtr<nsIFactory>   mFactory;
   346     nsCOMPtr<nsISupports>  mServiceObject;
   347 };
   349 #endif // nsComponentManager_h__

mercurial