Bug 641685 - Make plugin object map a singleton in the plugin process (r=bsmedberg)

This patches moves the object map (which tracks the PluginScriptableObjectChild
and PluginInstanceChild for a given NPObject) from the PluginModuleChild to
a global variable. This change prepares the way for having multiple PluginModuleChild
instances in a given plugin process.
This commit is contained in:
Bill McCloskey
2014-10-29 08:04:51 -07:00
parent 6ea204e520
commit ea4cd2e4e8
7 changed files with 165 additions and 132 deletions

View File

@@ -539,7 +539,7 @@ PluginScriptableObjectChild::~PluginScriptableObjectChild()
AssertPluginThread();
if (mObject) {
PluginModuleChild::current()->UnregisterActorForNPObject(mObject);
UnregisterActor(mObject);
if (mObject->_class == GetClass()) {
NS_ASSERTION(mType == Proxy, "Wrong type!");
@@ -569,8 +569,8 @@ PluginScriptableObjectChild::InitializeProxy()
return false;
}
if (!PluginModuleChild::current()->RegisterActorForNPObject(object, this)) {
NS_ERROR("RegisterActorForNPObject failed");
if (!RegisterActor(object)) {
NS_ERROR("RegisterActor failed");
return false;
}
@@ -594,8 +594,8 @@ PluginScriptableObjectChild::InitializeLocal(NPObject* aObject)
NS_ASSERTION(!mProtectCount, "Should be zero!");
mProtectCount++;
if (!PluginModuleChild::current()->RegisterActorForNPObject(aObject, this)) {
NS_ERROR("RegisterActorForNPObject failed");
if (!RegisterActor(aObject)) {
NS_ERROR("RegisterActor failed");
}
mObject = aObject;
@@ -688,7 +688,7 @@ PluginScriptableObjectChild::DropNPObject()
// We think we're about to be deleted, but we could be racing with the other
// process.
PluginModuleChild::current()->UnregisterActorForNPObject(mObject);
UnregisterActor(mObject);
mObject = nullptr;
SendUnprotect();
@@ -1181,3 +1181,105 @@ PluginScriptableObjectChild::Evaluate(NPString* aScript,
ConvertToVariant(result, *aResult);
return true;
}
nsTHashtable<PluginScriptableObjectChild::NPObjectData>* PluginScriptableObjectChild::sObjectMap;
bool
PluginScriptableObjectChild::RegisterActor(NPObject* aObject)
{
AssertPluginThread();
MOZ_ASSERT(aObject, "Null pointer!");
NPObjectData* d = sObjectMap->GetEntry(aObject);
if (!d) {
NS_ERROR("NPObject not in object table");
return false;
}
d->actor = this;
return true;
}
void
PluginScriptableObjectChild::UnregisterActor(NPObject* aObject)
{
AssertPluginThread();
MOZ_ASSERT(aObject, "Null pointer!");
NPObjectData* d = sObjectMap->GetEntry(aObject);
MOZ_ASSERT(d, "NPObject not in object table");
if (d) {
d->actor = nullptr;
}
}
/* static */ PluginScriptableObjectChild*
PluginScriptableObjectChild::GetActorForNPObject(NPObject* aObject)
{
AssertPluginThread();
MOZ_ASSERT(aObject, "Null pointer!");
NPObjectData* d = sObjectMap->GetEntry(aObject);
if (!d) {
NS_ERROR("Plugin using object not created with NPN_CreateObject?");
return nullptr;
}
return d->actor;
}
/* static */ void
PluginScriptableObjectChild::RegisterObject(NPObject* aObject, PluginInstanceChild* aInstance)
{
AssertPluginThread();
if (!sObjectMap) {
sObjectMap = new nsTHashtable<PluginScriptableObjectChild::NPObjectData>();
}
NPObjectData* d = sObjectMap->PutEntry(aObject);
MOZ_ASSERT(!d->instance, "New NPObject already mapped?");
d->instance = aInstance;
}
/* static */ void
PluginScriptableObjectChild::UnregisterObject(NPObject* aObject)
{
AssertPluginThread();
sObjectMap->RemoveEntry(aObject);
if (!sObjectMap->Count()) {
delete sObjectMap;
sObjectMap = nullptr;
}
}
/* static */ PluginInstanceChild*
PluginScriptableObjectChild::GetInstanceForNPObject(NPObject* aObject)
{
AssertPluginThread();
NPObjectData* d = sObjectMap->GetEntry(aObject);
if (!d) {
return nullptr;
}
return d->instance;
}
/* static */ PLDHashOperator
PluginScriptableObjectChild::CollectForInstance(NPObjectData* d, void* userArg)
{
PluginInstanceChild* instance = static_cast<PluginInstanceChild*>(userArg);
if (d->instance == instance) {
NPObject* o = d->GetKey();
instance->mDeletingHash->PutEntry(o);
}
return PL_DHASH_NEXT;
}
/* static */ void
PluginScriptableObjectChild::NotifyOfInstanceShutdown(PluginInstanceChild* aInstance)
{
AssertPluginThread();
sObjectMap->EnumerateEntries(CollectForInstance, aInstance);
}