fune/xpcom/components/nsComponentManager.h
Simon Giesecke ad01a10a3b Bug 1634281 - Use nsTHashMap instead of nsDataHashtable. r=xpcom-reviewers,necko-reviewers,jgilbert,nika,valentin
Note that this patch only transforms the use of the nsDataHashtable type alias
to a directly equivalent use of nsTHashMap. It does not change the specification
of the hash key type to make use of the key class deduction that nsTHashMap
allows for in some cases. That can be done in a separate step, but requires more
attention.

Differential Revision: https://phabricator.services.mozilla.com/D106008
2021-03-10 10:47:47 +00:00

279 lines
8.5 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsComponentManager_h__
#define nsComponentManager_h__
#include "nsXPCOM.h"
#include "nsIComponentManager.h"
#include "nsIComponentRegistrar.h"
#include "nsIMemoryReporter.h"
#include "nsIServiceManager.h"
#include "nsIFile.h"
#include "mozilla/ArenaAllocator.h"
#include "mozilla/Atomics.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Module.h"
#include "mozilla/Monitor.h"
#include "mozilla/UniquePtr.h"
#include "nsXULAppAPI.h"
#include "nsIFactory.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
#include "PLDHashTable.h"
#include "prtime.h"
#include "nsCOMPtr.h"
#include "nsWeakReference.h"
#include "nsCOMArray.h"
#include "nsTHashMap.h"
#include "nsInterfaceHashtable.h"
#include "nsClassHashtable.h"
#include "nsTArray.h"
#include "mozilla/Components.h"
#include "mozilla/Maybe.h"
#include "mozilla/Omnijar.h"
#include "mozilla/Attributes.h"
struct nsFactoryEntry;
struct PRThread;
#define NS_COMPONENTMANAGER_CID \
{ /* 91775d60-d5dc-11d2-92fb-00e09805570f */ \
0x91775d60, 0xd5dc, 0x11d2, { \
0x92, 0xfb, 0x00, 0xe0, 0x98, 0x05, 0x57, 0x0f \
} \
}
////////////////////////////////////////////////////////////////////////////////
extern const mozilla::Module kXPCOMModule;
namespace {
class EntryWrapper;
} // namespace
namespace mozilla {
namespace xpcom {
bool ProcessSelectorMatches(Module::ProcessSelector aSelector);
bool FastProcessSelectorMatches(Module::ProcessSelector aSelector);
} // namespace xpcom
} // namespace mozilla
class nsComponentManagerImpl final : public nsIComponentManager,
public nsIServiceManager,
public nsSupportsWeakReference,
public nsIComponentRegistrar,
public nsIInterfaceRequestor,
public nsIMemoryReporter {
public:
NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSICOMPONENTMANAGER
NS_DECL_NSICOMPONENTREGISTRAR
NS_DECL_NSIMEMORYREPORTER
static nsresult Create(nsISupports* aOuter, REFNSIID aIID, void** aResult);
nsresult RegistryLocationForFile(nsIFile* aFile, nsCString& aResult);
nsresult FileForRegistryLocation(const nsCString& aLocation, nsIFile** aSpec);
NS_DECL_NSISERVICEMANAGER
// nsComponentManagerImpl methods:
nsComponentManagerImpl();
static nsComponentManagerImpl* gComponentManager;
nsresult Init();
nsresult Shutdown(void);
nsresult FreeServices();
already_AddRefed<nsIFactory> FindFactory(const nsCID& aClass);
already_AddRefed<nsIFactory> FindFactory(const char* aContractID,
uint32_t aContractIDLen);
already_AddRefed<nsIFactory> LoadFactory(nsFactoryEntry* aEntry);
nsTHashMap<nsIDPointerHashKey, nsFactoryEntry*> mFactories;
nsTHashMap<nsCStringHashKey, nsFactoryEntry*> mContractIDs;
mozilla::Monitor mLock;
mozilla::Maybe<EntryWrapper> LookupByCID(const nsID& aCID);
mozilla::Maybe<EntryWrapper> LookupByCID(const mozilla::MonitorAutoLock&,
const nsID& aCID);
mozilla::Maybe<EntryWrapper> LookupByContractID(
const nsACString& aContractID);
mozilla::Maybe<EntryWrapper> LookupByContractID(
const mozilla::MonitorAutoLock&, const nsACString& aContractID);
nsresult GetService(mozilla::xpcom::ModuleID, const nsIID& aIID,
void** aResult);
static bool JSLoaderReady() { return gComponentManager->mJSLoaderReady; }
static void InitializeStaticModules();
static void InitializeModuleLocations();
struct ComponentLocation {
NSLocationType type;
mozilla::FileLocation location;
};
class ComponentLocationComparator {
public:
bool Equals(const ComponentLocation& aA,
const ComponentLocation& aB) const {
return (aA.type == aB.type && aA.location.Equals(aB.location));
}
};
static nsTArray<ComponentLocation>* sModuleLocations;
class KnownModule {
public:
/**
* Static or binary module.
*/
explicit KnownModule(const mozilla::Module* aModule)
: mModule(aModule), mLoaded(false), mFailed(false) {}
explicit KnownModule(mozilla::FileLocation& aFile)
: mModule(nullptr), mFile(aFile), mLoaded(false), mFailed(false) {}
~KnownModule() {
if (mLoaded && mModule->unloadProc) {
mModule->unloadProc();
}
}
bool Load();
const mozilla::Module* Module() const { return mModule; }
/**
* For error logging, get a description of this module, either the
* file path, or <static module>.
*/
nsCString Description() const;
private:
const mozilla::Module* mModule;
mozilla::FileLocation mFile;
bool mLoaded;
bool mFailed;
};
// The KnownModule is kept alive by these members, it is
// referenced by pointer from the factory entries.
nsTArray<mozilla::UniquePtr<KnownModule>> mKnownStaticModules;
// The key is the URI string of the module
nsClassHashtable<nsCStringHashKey, KnownModule> mKnownModules;
// Mutex not held
void RegisterModule(const mozilla::Module* aModule);
// Mutex held
void RegisterCIDEntryLocked(const mozilla::Module::CIDEntry* aEntry,
KnownModule* aModule);
void RegisterContractIDLocked(const mozilla::Module::ContractIDEntry* aEntry);
// Mutex not held
void RegisterManifest(NSLocationType aType, mozilla::FileLocation& aFile,
bool aChromeOnly);
struct ManifestProcessingContext {
ManifestProcessingContext(NSLocationType aType,
mozilla::FileLocation& aFile, bool aChromeOnly)
: mType(aType), mFile(aFile), mChromeOnly(aChromeOnly) {}
~ManifestProcessingContext() = default;
NSLocationType mType;
mozilla::FileLocation mFile;
bool mChromeOnly;
};
void ManifestManifest(ManifestProcessingContext& aCx, int aLineNo,
char* const* aArgv);
void ManifestComponent(ManifestProcessingContext& aCx, int aLineNo,
char* const* aArgv);
void ManifestContract(ManifestProcessingContext& aCx, int aLineNo,
char* const* aArgv);
void ManifestCategory(ManifestProcessingContext& aCx, int aLineNo,
char* const* aArgv);
void RereadChromeManifests(bool aChromeOnly = true);
// Shutdown
enum {
NOT_INITIALIZED,
NORMAL,
SHUTDOWN_IN_PROGRESS,
SHUTDOWN_COMPLETE
} mStatus;
mozilla::ArenaAllocator<1024 * 1, 8> mArena;
struct PendingServiceInfo {
const nsCID* cid;
PRThread* thread;
};
inline PendingServiceInfo* AddPendingService(const nsCID& aServiceCID,
PRThread* aThread);
inline void RemovePendingService(mozilla::MonitorAutoLock& aLock,
const nsCID& aServiceCID);
inline PRThread* GetPendingServiceThread(const nsCID& aServiceCID) const;
nsTArray<PendingServiceInfo> mPendingServices;
bool mJSLoaderReady = false;
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
private:
~nsComponentManagerImpl();
nsresult GetServiceLocked(mozilla::Maybe<mozilla::MonitorAutoLock>& aLock,
EntryWrapper& aEntry, const nsIID& aIID,
void** aResult);
};
#define NS_MAX_FILENAME_LEN 1024
#define NS_ERROR_IS_DIR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XPCOM, 24)
struct nsFactoryEntry {
nsFactoryEntry(const mozilla::Module::CIDEntry* aEntry,
nsComponentManagerImpl::KnownModule* aModule);
// nsIComponentRegistrar.registerFactory support
nsFactoryEntry(const nsCID& aClass, nsIFactory* aFactory);
~nsFactoryEntry();
already_AddRefed<nsIFactory> GetFactory();
nsresult CreateInstance(nsISupports* aOuter, const nsIID& aIID,
void** aResult);
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
const mozilla::Module::CIDEntry* mCIDEntry;
nsComponentManagerImpl::KnownModule* mModule;
nsCOMPtr<nsIFactory> mFactory;
nsCOMPtr<nsISupports> mServiceObject;
};
#endif // nsComponentManager_h__