mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-11-03 01:38:46 +02:00
Bug 1773770: Part 12 - Remove XPCOM Module infrastructure. r=xpcom-reviewers,nika
Differential Revision: https://phabricator.services.mozilla.com/D149439
This commit is contained in:
parent
76050d3c60
commit
12faebc6e9
7 changed files with 17 additions and 418 deletions
|
|
@ -39,9 +39,6 @@ extern bool gXPCOMMainThreadEventsAreDoomed;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
# include "nsStringFwd.h"
|
# include "nsStringFwd.h"
|
||||||
namespace mozilla {
|
|
||||||
struct Module;
|
|
||||||
} // namespace mozilla
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,6 @@ struct XREShellData;
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
class XREAppData;
|
class XREAppData;
|
||||||
struct BootstrapConfig;
|
struct BootstrapConfig;
|
||||||
struct Module;
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -219,11 +218,6 @@ nsresult XRE_GetFileFromPath(const char* aPath, nsIFile** aResult);
|
||||||
*/
|
*/
|
||||||
nsresult XRE_GetBinaryPath(nsIFile** aResult);
|
nsresult XRE_GetBinaryPath(nsIFile** aResult);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the static module built in to libxul.
|
|
||||||
*/
|
|
||||||
const mozilla::Module* XRE_GetStaticModule();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lock a profile directory using platform-specific semantics.
|
* Lock a profile directory using platform-specific semantics.
|
||||||
*
|
*
|
||||||
|
|
@ -257,13 +251,6 @@ nsresult XRE_LockProfileDirectory(nsIFile* aDirectory,
|
||||||
nsresult XRE_InitEmbedding2(nsIFile* aLibXULDirectory, nsIFile* aAppDirectory,
|
nsresult XRE_InitEmbedding2(nsIFile* aLibXULDirectory, nsIFile* aAppDirectory,
|
||||||
nsIDirectoryServiceProvider* aAppDirProvider);
|
nsIDirectoryServiceProvider* aAppDirProvider);
|
||||||
|
|
||||||
/**
|
|
||||||
* Register static XPCOM component information.
|
|
||||||
* This method may be called at any time before or after XRE_main or
|
|
||||||
* XRE_InitEmbedding.
|
|
||||||
*/
|
|
||||||
nsresult XRE_AddStaticComponent(const mozilla::Module* aComponent);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register XPCOM components found in an array of files/directories.
|
* Register XPCOM components found in an array of files/directories.
|
||||||
* This method may be called at any time before or after XRE_main or
|
* This method may be called at any time before or after XRE_main or
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,7 @@
|
||||||
#ifndef mozilla_GenericFactory_h
|
#ifndef mozilla_GenericFactory_h
|
||||||
#define mozilla_GenericFactory_h
|
#define mozilla_GenericFactory_h
|
||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "nsIFactory.h"
|
||||||
|
|
||||||
#include "mozilla/Module.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
|
|
@ -19,10 +17,10 @@ namespace mozilla {
|
||||||
* module.
|
* module.
|
||||||
*/
|
*/
|
||||||
class GenericFactory final : public nsIFactory {
|
class GenericFactory final : public nsIFactory {
|
||||||
~GenericFactory() {}
|
~GenericFactory() = default;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef Module::ConstructorProcPtr ConstructorProcPtr;
|
typedef nsresult (*ConstructorProcPtr)(const nsIID& aIID, void** aResult);
|
||||||
|
|
||||||
NS_DECL_THREADSAFE_ISUPPORTS
|
NS_DECL_THREADSAFE_ISUPPORTS
|
||||||
NS_DECL_NSIFACTORY
|
NS_DECL_NSIFACTORY
|
||||||
|
|
|
||||||
|
|
@ -8,31 +8,12 @@
|
||||||
#define mozilla_Module_h
|
#define mozilla_Module_h
|
||||||
|
|
||||||
#include "nscore.h"
|
#include "nscore.h"
|
||||||
#include "nsID.h"
|
|
||||||
#include "nsIFactory.h"
|
|
||||||
#include "nsCOMPtr.h" // for already_AddRefed
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
/**
|
namespace Module {
|
||||||
* A module implements one or more XPCOM components. This structure is used
|
|
||||||
* for binary modules.
|
|
||||||
*/
|
|
||||||
struct Module {
|
|
||||||
static const unsigned int kVersion = 104;
|
|
||||||
|
|
||||||
struct CIDEntry;
|
|
||||||
|
|
||||||
typedef already_AddRefed<nsIFactory> (*GetFactoryProcPtr)(
|
|
||||||
const Module& module, const CIDEntry& entry);
|
|
||||||
|
|
||||||
typedef nsresult (*ConstructorProcPtr)(const nsIID& aIID, void** aResult);
|
|
||||||
|
|
||||||
typedef nsresult (*LoadFuncPtr)();
|
|
||||||
typedef void (*UnloadFuncPtr)();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This selector allows CIDEntrys to be marked so that they're only loaded
|
* This selector allows components to be marked so that they're only loaded
|
||||||
* into certain kinds of processes. Selectors can be combined.
|
* into certain kinds of processes. Selectors can be combined.
|
||||||
*/
|
*/
|
||||||
// Note: This must be kept in sync with the selector matching in
|
// Note: This must be kept in sync with the selector matching in
|
||||||
|
|
@ -88,76 +69,6 @@ struct Module {
|
||||||
NO_TASKS = 0x0,
|
NO_TASKS = 0x0,
|
||||||
ALL_TASKS = 0xFFFF,
|
ALL_TASKS = 0xFFFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* The constructor callback is an implementation detail of the default binary
|
|
||||||
* loader and may be null.
|
|
||||||
*/
|
|
||||||
struct CIDEntry {
|
|
||||||
const nsCID* cid;
|
|
||||||
bool service;
|
|
||||||
GetFactoryProcPtr getFactoryProc;
|
|
||||||
ConstructorProcPtr constructorProc;
|
|
||||||
ProcessSelector processSelector;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct ContractIDEntry {
|
|
||||||
const char* contractid;
|
|
||||||
nsID const* cid;
|
|
||||||
ProcessSelector processSelector;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct CategoryEntry {
|
|
||||||
const char* category;
|
|
||||||
const char* entry;
|
|
||||||
const char* value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Binary compatibility check, should be kModuleVersion.
|
|
||||||
*/
|
|
||||||
unsigned int mVersion;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An array of CIDs (class IDs) implemented by this module. The final entry
|
|
||||||
* should be { nullptr }.
|
|
||||||
*/
|
|
||||||
const CIDEntry* mCIDs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An array of mappings from contractid to CID. The final entry should
|
|
||||||
* be { nullptr }.
|
|
||||||
*/
|
|
||||||
const ContractIDEntry* mContractIDs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An array of category manager entries. The final entry should be
|
|
||||||
* { nullptr }.
|
|
||||||
*/
|
|
||||||
const CategoryEntry* mCategoryEntries;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When the component manager tries to get the factory for a CID, it first
|
|
||||||
* checks for this module-level getfactory callback. If this function is
|
|
||||||
* not implemented, it checks the CIDEntry getfactory callback. If that is
|
|
||||||
* also nullptr, a generic factory is generated using the CIDEntry
|
|
||||||
* constructor callback which must be non-nullptr.
|
|
||||||
*/
|
|
||||||
GetFactoryProcPtr getFactoryProc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Optional Function which are called when this module is loaded and
|
|
||||||
* at shutdown. These are not C++ constructor/destructors to avoid
|
|
||||||
* calling them too early in startup or too late in shutdown.
|
|
||||||
*/
|
|
||||||
LoadFuncPtr loadProc;
|
|
||||||
UnloadFuncPtr unloadProc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Optional flags which control whether the module loads on a process-type
|
|
||||||
* basis.
|
|
||||||
*/
|
|
||||||
ProcessSelector selector;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
||||||
|
#include "mozilla/AlreadyAddRefed.h"
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/Module.h"
|
#include "mozilla/Module.h"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -163,7 +163,7 @@ class MOZ_STACK_CLASS EntryWrapper final {
|
||||||
return mEntry.match((Matcher()))
|
return mEntry.match((Matcher()))
|
||||||
|
|
||||||
const nsID& CID() {
|
const nsID& CID() {
|
||||||
MATCH(const nsID&, return *entry->mCIDEntry->cid, return entry->CID());
|
MATCH(const nsID&, return entry->mCID, return entry->CID());
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsIFactory> GetFactory() {
|
already_AddRefed<nsIFactory> GetFactory() {
|
||||||
|
|
@ -202,14 +202,11 @@ class MOZ_STACK_CLASS EntryWrapper final {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the description string for the module this entry belongs to. For
|
* Returns the description string for the module this entry belongs to.
|
||||||
* static entries, always returns "<unknown module>".
|
* Currently always returns "<unknown module>".
|
||||||
*/
|
*/
|
||||||
nsCString ModuleDescription() {
|
nsCString ModuleDescription() {
|
||||||
MATCH(nsCString,
|
return "<unknown module>"_ns;
|
||||||
return entry->mModule ? entry->mModule->Description()
|
|
||||||
: "<unknown module>"_ns,
|
|
||||||
return "<unknown module>"_ns);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -271,17 +268,6 @@ nsComponentManagerImpl::nsComponentManagerImpl()
|
||||||
mLock("nsComponentManagerImpl.mLock"),
|
mLock("nsComponentManagerImpl.mLock"),
|
||||||
mStatus(NOT_INITIALIZED) {}
|
mStatus(NOT_INITIALIZED) {}
|
||||||
|
|
||||||
static nsTArray<const mozilla::Module*>* sExtraStaticModules;
|
|
||||||
|
|
||||||
/* static */
|
|
||||||
void nsComponentManagerImpl::InitializeStaticModules() {
|
|
||||||
if (sExtraStaticModules) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
sExtraStaticModules = new nsTArray<const mozilla::Module*>;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsTArray<nsComponentManagerImpl::ComponentLocation>*
|
nsTArray<nsComponentManagerImpl::ComponentLocation>*
|
||||||
nsComponentManagerImpl::sModuleLocations;
|
nsComponentManagerImpl::sModuleLocations;
|
||||||
|
|
||||||
|
|
@ -350,14 +336,8 @@ nsresult nsComponentManagerImpl::Init() {
|
||||||
nsCOMPtr<nsIFile> appDir =
|
nsCOMPtr<nsIFile> appDir =
|
||||||
GetLocationFromDirectoryService(NS_XPCOM_CURRENT_PROCESS_DIR);
|
GetLocationFromDirectoryService(NS_XPCOM_CURRENT_PROCESS_DIR);
|
||||||
|
|
||||||
InitializeStaticModules();
|
|
||||||
|
|
||||||
nsCategoryManager::GetSingleton()->SuppressNotifications(true);
|
nsCategoryManager::GetSingleton()->SuppressNotifications(true);
|
||||||
|
|
||||||
for (uint32_t i = 0; i < sExtraStaticModules->Length(); ++i) {
|
|
||||||
RegisterModule((*sExtraStaticModules)[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto* catMan = nsCategoryManager::GetSingleton();
|
auto* catMan = nsCategoryManager::GetSingleton();
|
||||||
for (const auto& cat : gStaticCategories) {
|
for (const auto& cat : gStaticCategories) {
|
||||||
for (const auto& entry : cat) {
|
for (const auto& entry : cat) {
|
||||||
|
|
@ -468,8 +448,6 @@ nsresult nsComponentManagerImpl::Init() {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int kModuleVersionWithSelector = 51;
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static void AssertNotMallocAllocated(T* aPtr) {
|
static void AssertNotMallocAllocated(T* aPtr) {
|
||||||
#if defined(DEBUG) && defined(MOZ_MEMORY)
|
#if defined(DEBUG) && defined(MOZ_MEMORY)
|
||||||
|
|
@ -510,140 +488,6 @@ static void AssertNotStackAllocated(T* aPtr) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline nsCString AsLiteralCString(const char* aStr) {
|
|
||||||
AssertNotMallocAllocated(aStr);
|
|
||||||
AssertNotStackAllocated(aStr);
|
|
||||||
|
|
||||||
nsCString str;
|
|
||||||
str.AssignLiteral(aStr, strlen(aStr));
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsComponentManagerImpl::RegisterModule(const mozilla::Module* aModule) {
|
|
||||||
mLock.AssertNotCurrentThreadOwns();
|
|
||||||
|
|
||||||
if (aModule->mVersion >= kModuleVersionWithSelector &&
|
|
||||||
!ProcessSelectorMatches(aModule->selector)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
// Scope the monitor so that we don't hold it while calling into the
|
|
||||||
// category manager.
|
|
||||||
MonitorAutoLock lock(mLock);
|
|
||||||
|
|
||||||
KnownModule* m = new KnownModule(aModule);
|
|
||||||
mKnownStaticModules.AppendElement(m);
|
|
||||||
|
|
||||||
if (aModule->mCIDs) {
|
|
||||||
const mozilla::Module::CIDEntry* entry;
|
|
||||||
for (entry = aModule->mCIDs; entry->cid; ++entry) {
|
|
||||||
RegisterCIDEntryLocked(entry, m);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aModule->mContractIDs) {
|
|
||||||
const mozilla::Module::ContractIDEntry* entry;
|
|
||||||
for (entry = aModule->mContractIDs; entry->contractid; ++entry) {
|
|
||||||
RegisterContractIDLocked(entry);
|
|
||||||
}
|
|
||||||
MOZ_ASSERT(!entry->cid, "Incorrectly terminated contract list");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aModule->mCategoryEntries) {
|
|
||||||
const mozilla::Module::CategoryEntry* entry;
|
|
||||||
for (entry = aModule->mCategoryEntries; entry->category; ++entry)
|
|
||||||
nsCategoryManager::GetSingleton()->AddCategoryEntry(
|
|
||||||
AsLiteralCString(entry->category), AsLiteralCString(entry->entry),
|
|
||||||
AsLiteralCString(entry->value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsComponentManagerImpl::RegisterCIDEntryLocked(
|
|
||||||
const mozilla::Module::CIDEntry* aEntry, KnownModule* aModule) {
|
|
||||||
mLock.AssertCurrentThreadOwns();
|
|
||||||
|
|
||||||
if (!ProcessSelectorMatches(aEntry->processSelector)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
// If we're still in the static initialization phase, check that we're not
|
|
||||||
// registering something that was already registered.
|
|
||||||
if (mStatus != NORMAL) {
|
|
||||||
if (StaticComponents::LookupByCID(*aEntry->cid)) {
|
|
||||||
MOZ_CRASH_UNSAFE_PRINTF(
|
|
||||||
"While registering XPCOM module %s, trying to re-register CID '%s' "
|
|
||||||
"already registered by a static component.",
|
|
||||||
aModule->Description().get(), AutoIDString(*aEntry->cid).get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mFactories.WithEntryHandle(aEntry->cid, [&](auto&& entry) {
|
|
||||||
mLock.AssertCurrentThreadOwns();
|
|
||||||
if (entry) {
|
|
||||||
nsFactoryEntry* f = entry.Data();
|
|
||||||
NS_WARNING("Re-registering a CID?");
|
|
||||||
|
|
||||||
nsCString existing;
|
|
||||||
if (f->mModule) {
|
|
||||||
existing = f->mModule->Description();
|
|
||||||
} else {
|
|
||||||
existing = "<unknown module>";
|
|
||||||
}
|
|
||||||
MonitorAutoUnlock unlock(mLock);
|
|
||||||
LogMessage(
|
|
||||||
"While registering XPCOM module %s, trying to re-register CID '%s' "
|
|
||||||
"already registered by %s.",
|
|
||||||
aModule->Description().get(), AutoIDString(*aEntry->cid).get(),
|
|
||||||
existing.get());
|
|
||||||
} else {
|
|
||||||
entry.Insert(new nsFactoryEntry(aEntry, aModule));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void nsComponentManagerImpl::RegisterContractIDLocked(
|
|
||||||
const mozilla::Module::ContractIDEntry* aEntry) {
|
|
||||||
mLock.AssertCurrentThreadOwns();
|
|
||||||
|
|
||||||
if (!ProcessSelectorMatches(aEntry->processSelector)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
// If we're still in the static initialization phase, check that we're not
|
|
||||||
// registering something that was already registered.
|
|
||||||
if (mStatus != NORMAL) {
|
|
||||||
if (const StaticModule* module = StaticComponents::LookupByContractID(
|
|
||||||
nsAutoCString(aEntry->contractid))) {
|
|
||||||
MOZ_CRASH_UNSAFE_PRINTF(
|
|
||||||
"Could not map contract ID '%s' to CID %s because it is already "
|
|
||||||
"mapped to CID %s.",
|
|
||||||
aEntry->contractid, AutoIDString(*aEntry->cid).get(),
|
|
||||||
AutoIDString(module->CID()).get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
nsFactoryEntry* f = mFactories.Get(aEntry->cid);
|
|
||||||
if (!f) {
|
|
||||||
NS_WARNING("No CID found when attempting to map contract ID");
|
|
||||||
|
|
||||||
MonitorAutoUnlock unlock(mLock);
|
|
||||||
LogMessage(
|
|
||||||
"Could not map contract ID '%s' to CID %s because no implementation of "
|
|
||||||
"the CID is registered.",
|
|
||||||
aEntry->contractid, AutoIDString(*aEntry->cid).get());
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mContractIDs.InsertOrUpdate(AsLiteralCString(aEntry->contractid), f);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void DoRegisterManifest(NSLocationType aType, FileLocation& aFile,
|
static void DoRegisterManifest(NSLocationType aType, FileLocation& aFile,
|
||||||
bool aChromeOnly) {
|
bool aChromeOnly) {
|
||||||
auto result = URLPreloader::Read(aFile);
|
auto result = URLPreloader::Read(aFile);
|
||||||
|
|
@ -693,28 +537,6 @@ void nsComponentManagerImpl::RereadChromeManifests(bool aChromeOnly) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nsComponentManagerImpl::KnownModule::Load() {
|
|
||||||
if (mFailed) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
MOZ_ASSERT(mModule);
|
|
||||||
if (!mLoaded) {
|
|
||||||
if (mModule->loadProc) {
|
|
||||||
nsresult rv = mModule->loadProc();
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
mFailed = true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mLoaded = true;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsCString nsComponentManagerImpl::KnownModule::Description() const {
|
|
||||||
return "<static module>"_ns;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsresult nsComponentManagerImpl::Shutdown(void) {
|
nsresult nsComponentManagerImpl::Shutdown(void) {
|
||||||
MOZ_ASSERT(NORMAL == mStatus);
|
MOZ_ASSERT(NORMAL == mStatus);
|
||||||
|
|
||||||
|
|
@ -729,11 +551,9 @@ nsresult nsComponentManagerImpl::Shutdown(void) {
|
||||||
// Release all cached factories
|
// Release all cached factories
|
||||||
mContractIDs.Clear();
|
mContractIDs.Clear();
|
||||||
mFactories.Clear(); // XXX release the objects, don't just clear
|
mFactories.Clear(); // XXX release the objects, don't just clear
|
||||||
mKnownStaticModules.Clear();
|
|
||||||
|
|
||||||
StaticComponents::Shutdown();
|
StaticComponents::Shutdown();
|
||||||
|
|
||||||
delete sExtraStaticModules;
|
|
||||||
delete sModuleLocations;
|
delete sModuleLocations;
|
||||||
|
|
||||||
mStatus = SHUTDOWN_COMPLETE;
|
mStatus = SHUTDOWN_COMPLETE;
|
||||||
|
|
@ -799,7 +619,7 @@ Maybe<EntryWrapper> nsComponentManagerImpl::LookupByContractID(
|
||||||
// UnregisterFactory might have left a stale nsFactoryEntry in
|
// UnregisterFactory might have left a stale nsFactoryEntry in
|
||||||
// mContractIDs, so we should check to see whether this entry has
|
// mContractIDs, so we should check to see whether this entry has
|
||||||
// anything useful.
|
// anything useful.
|
||||||
if (entry->mModule || entry->mFactory || entry->mServiceObject) {
|
if (entry->mFactory || entry->mServiceObject) {
|
||||||
return Some(EntryWrapper(entry));
|
return Some(EntryWrapper(entry));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1382,11 +1202,11 @@ nsComponentManagerImpl::RegisterFactory(const nsCID& aClass, const char* aName,
|
||||||
auto f = MakeUnique<nsFactoryEntry>(aClass, aFactory);
|
auto f = MakeUnique<nsFactoryEntry>(aClass, aFactory);
|
||||||
|
|
||||||
MonitorAutoLock lock(mLock);
|
MonitorAutoLock lock(mLock);
|
||||||
return mFactories.WithEntryHandle(f->mCIDEntry->cid, [&](auto&& entry) {
|
return mFactories.WithEntryHandle(&f->mCID, [&](auto&& entry) {
|
||||||
if (entry) {
|
if (entry) {
|
||||||
return NS_ERROR_FACTORY_EXISTS;
|
return NS_ERROR_FACTORY_EXISTS;
|
||||||
}
|
}
|
||||||
if (StaticComponents::LookupByCID(*f->mCIDEntry->cid)) {
|
if (StaticComponents::LookupByCID(f->mCID)) {
|
||||||
return NS_ERROR_FACTORY_EXISTS;
|
return NS_ERROR_FACTORY_EXISTS;
|
||||||
}
|
}
|
||||||
if (aContractID) {
|
if (aContractID) {
|
||||||
|
|
@ -1541,20 +1361,16 @@ size_t nsComponentManagerImpl::SizeOfIncludingThis(
|
||||||
n += key.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
n += key.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
||||||
}
|
}
|
||||||
|
|
||||||
n += sExtraStaticModules->ShallowSizeOfIncludingThis(aMallocSizeOf);
|
|
||||||
if (sModuleLocations) {
|
if (sModuleLocations) {
|
||||||
n += sModuleLocations->ShallowSizeOfIncludingThis(aMallocSizeOf);
|
n += sModuleLocations->ShallowSizeOfIncludingThis(aMallocSizeOf);
|
||||||
}
|
}
|
||||||
|
|
||||||
n += mKnownStaticModules.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
|
||||||
|
|
||||||
n += mPendingServices.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
n += mPendingServices.ShallowSizeOfExcludingThis(aMallocSizeOf);
|
||||||
|
|
||||||
// Measurement of the following members may be added later if DMD finds it is
|
// Measurement of the following members may be added later if DMD finds it is
|
||||||
// worthwhile:
|
// worthwhile:
|
||||||
// - mMon
|
// - mMon
|
||||||
// - sModuleLocations' entries
|
// - sModuleLocations' entries
|
||||||
// - mKnownStaticModules' entries?
|
|
||||||
|
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
@ -1563,63 +1379,13 @@ size_t nsComponentManagerImpl::SizeOfIncludingThis(
|
||||||
// nsFactoryEntry
|
// nsFactoryEntry
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
nsFactoryEntry::nsFactoryEntry(const mozilla::Module::CIDEntry* aEntry,
|
|
||||||
nsComponentManagerImpl::KnownModule* aModule)
|
|
||||||
: mCIDEntry(aEntry), mModule(aModule) {}
|
|
||||||
|
|
||||||
nsFactoryEntry::nsFactoryEntry(const nsCID& aCID, nsIFactory* aFactory)
|
nsFactoryEntry::nsFactoryEntry(const nsCID& aCID, nsIFactory* aFactory)
|
||||||
: mCIDEntry(nullptr), mModule(nullptr), mFactory(aFactory) {
|
: mCID(aCID), mFactory(aFactory) {
|
||||||
auto* e = new mozilla::Module::CIDEntry();
|
|
||||||
auto* cid = new nsCID;
|
|
||||||
*cid = aCID;
|
|
||||||
e->cid = cid;
|
|
||||||
mCIDEntry = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsFactoryEntry::~nsFactoryEntry() {
|
|
||||||
// If this was a RegisterFactory entry, we own the CIDEntry/CID
|
|
||||||
if (!mModule) {
|
|
||||||
delete mCIDEntry->cid;
|
|
||||||
delete mCIDEntry;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
already_AddRefed<nsIFactory> nsFactoryEntry::GetFactory() {
|
already_AddRefed<nsIFactory> nsFactoryEntry::GetFactory() {
|
||||||
nsComponentManagerImpl::gComponentManager->mLock.AssertNotCurrentThreadOwns();
|
nsComponentManagerImpl::gComponentManager->mLock.AssertNotCurrentThreadOwns();
|
||||||
|
|
||||||
if (!mFactory) {
|
|
||||||
// RegisterFactory then UnregisterFactory can leave an entry in mContractIDs
|
|
||||||
// pointing to an unusable nsFactoryEntry.
|
|
||||||
if (!mModule) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!mModule->Load()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't set mFactory directly, it needs to be locked
|
|
||||||
nsCOMPtr<nsIFactory> factory;
|
|
||||||
|
|
||||||
if (mModule->Module()->getFactoryProc) {
|
|
||||||
factory =
|
|
||||||
mModule->Module()->getFactoryProc(*mModule->Module(), *mCIDEntry);
|
|
||||||
} else if (mCIDEntry->getFactoryProc) {
|
|
||||||
factory = mCIDEntry->getFactoryProc(*mModule->Module(), *mCIDEntry);
|
|
||||||
} else {
|
|
||||||
NS_ASSERTION(mCIDEntry->constructorProc, "no getfactory or constructor");
|
|
||||||
factory = new mozilla::GenericFactory(mCIDEntry->constructorProc);
|
|
||||||
}
|
|
||||||
if (!factory) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
MonitorAutoLock lock(nsComponentManagerImpl::gComponentManager->mLock);
|
|
||||||
// Threads can race to set mFactory
|
|
||||||
if (!mFactory) {
|
|
||||||
factory.swap(mFactory);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
nsCOMPtr<nsIFactory> factory = mFactory;
|
nsCOMPtr<nsIFactory> factory = mFactory;
|
||||||
return factory.forget();
|
return factory.forget();
|
||||||
}
|
}
|
||||||
|
|
@ -1635,8 +1401,7 @@ size_t nsFactoryEntry::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) {
|
||||||
|
|
||||||
// Measurement of the following members may be added later if DMD finds it is
|
// Measurement of the following members may be added later if DMD finds it is
|
||||||
// worthwhile:
|
// worthwhile:
|
||||||
// - mCIDEntry;
|
// - mCID;
|
||||||
// - mModule;
|
|
||||||
// - mFactory;
|
// - mFactory;
|
||||||
// - mServiceObject;
|
// - mServiceObject;
|
||||||
|
|
||||||
|
|
@ -1674,20 +1439,6 @@ nsresult NS_GetComponentRegistrar(nsIComponentRegistrar** aResult) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_XPCOM_API(nsresult)
|
|
||||||
XRE_AddStaticComponent(const mozilla::Module* aComponent) {
|
|
||||||
nsComponentManagerImpl::InitializeStaticModules();
|
|
||||||
sExtraStaticModules->AppendElement(aComponent);
|
|
||||||
|
|
||||||
if (nsComponentManagerImpl::gComponentManager &&
|
|
||||||
nsComponentManagerImpl::NORMAL ==
|
|
||||||
nsComponentManagerImpl::gComponentManager->mStatus) {
|
|
||||||
nsComponentManagerImpl::gComponentManager->RegisterModule(aComponent);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsComponentManagerImpl::AddBootstrappedManifestLocation(nsIFile* aLocation) {
|
nsComponentManagerImpl::AddBootstrappedManifestLocation(nsIFile* aLocation) {
|
||||||
NS_ENSURE_ARG_POINTER(aLocation);
|
NS_ENSURE_ARG_POINTER(aLocation);
|
||||||
|
|
|
||||||
|
|
@ -137,48 +137,6 @@ class nsComponentManagerImpl final : public nsIComponentManager,
|
||||||
|
|
||||||
static nsTArray<ComponentLocation>* sModuleLocations;
|
static nsTArray<ComponentLocation>* sModuleLocations;
|
||||||
|
|
||||||
class KnownModule {
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Static or binary module.
|
|
||||||
*/
|
|
||||||
explicit KnownModule(const mozilla::Module* aModule)
|
|
||||||
: mModule(aModule), 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;
|
|
||||||
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;
|
|
||||||
|
|
||||||
// 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
|
// Mutex not held
|
||||||
void RegisterManifest(NSLocationType aType, mozilla::FileLocation& aFile,
|
void RegisterManifest(NSLocationType aType, mozilla::FileLocation& aFile,
|
||||||
bool aChromeOnly);
|
bool aChromeOnly);
|
||||||
|
|
@ -240,13 +198,10 @@ class nsComponentManagerImpl final : public nsIComponentManager,
|
||||||
#define NS_ERROR_IS_DIR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XPCOM, 24)
|
#define NS_ERROR_IS_DIR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XPCOM, 24)
|
||||||
|
|
||||||
struct nsFactoryEntry {
|
struct nsFactoryEntry {
|
||||||
nsFactoryEntry(const mozilla::Module::CIDEntry* aEntry,
|
|
||||||
nsComponentManagerImpl::KnownModule* aModule);
|
|
||||||
|
|
||||||
// nsIComponentRegistrar.registerFactory support
|
// nsIComponentRegistrar.registerFactory support
|
||||||
nsFactoryEntry(const nsCID& aClass, nsIFactory* aFactory);
|
nsFactoryEntry(const nsCID& aClass, nsIFactory* aFactory);
|
||||||
|
|
||||||
~nsFactoryEntry();
|
~nsFactoryEntry() = default;
|
||||||
|
|
||||||
already_AddRefed<nsIFactory> GetFactory();
|
already_AddRefed<nsIFactory> GetFactory();
|
||||||
|
|
||||||
|
|
@ -254,8 +209,7 @@ struct nsFactoryEntry {
|
||||||
|
|
||||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
|
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
|
||||||
|
|
||||||
const mozilla::Module::CIDEntry* mCIDEntry;
|
const nsCID mCID;
|
||||||
nsComponentManagerImpl::KnownModule* mModule;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFactory> mFactory;
|
nsCOMPtr<nsIFactory> mFactory;
|
||||||
nsCOMPtr<nsISupports> mServiceObject;
|
nsCOMPtr<nsISupports> mServiceObject;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue