xpcom/components/nsComponentManager.h

changeset 0
6474c204b198
     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__

mercurial