Home | History | Annotate | Download | only in pepper
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/renderer/pepper/host_var_tracker.h"
      6 
      7 #include "base/logging.h"
      8 #include "content/renderer/pepper/host_array_buffer_var.h"
      9 #include "content/renderer/pepper/npobject_var.h"
     10 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
     11 #include "ppapi/c/pp_var.h"
     12 
     13 using ppapi::ArrayBufferVar;
     14 using ppapi::NPObjectVar;
     15 
     16 namespace content {
     17 
     18 HostVarTracker::HostVarTracker()
     19   : VarTracker(SINGLE_THREADED),
     20     last_shared_memory_map_id_(0) {
     21 }
     22 
     23 HostVarTracker::~HostVarTracker() {
     24 }
     25 
     26 ArrayBufferVar* HostVarTracker::CreateArrayBuffer(uint32 size_in_bytes) {
     27   return new HostArrayBufferVar(size_in_bytes);
     28 }
     29 
     30 ArrayBufferVar* HostVarTracker::CreateShmArrayBuffer(
     31     uint32 size_in_bytes,
     32     base::SharedMemoryHandle handle) {
     33   return new HostArrayBufferVar(size_in_bytes, handle);
     34 }
     35 
     36 void HostVarTracker::AddNPObjectVar(NPObjectVar* object_var) {
     37   CheckThreadingPreconditions();
     38 
     39   InstanceMap::iterator found_instance = instance_map_.find(
     40       object_var->pp_instance());
     41   if (found_instance == instance_map_.end()) {
     42     // Lazily create the instance map.
     43     DCHECK(object_var->pp_instance() != 0);
     44     found_instance = instance_map_.insert(std::make_pair(
     45         object_var->pp_instance(),
     46         linked_ptr<NPObjectToNPObjectVarMap>(new NPObjectToNPObjectVarMap))).
     47             first;
     48   }
     49   NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get();
     50 
     51   DCHECK(np_object_map->find(object_var->np_object()) ==
     52          np_object_map->end()) << "NPObjectVar already in map";
     53   np_object_map->insert(std::make_pair(object_var->np_object(), object_var));
     54 }
     55 
     56 void HostVarTracker::RemoveNPObjectVar(NPObjectVar* object_var) {
     57   CheckThreadingPreconditions();
     58 
     59   InstanceMap::iterator found_instance = instance_map_.find(
     60       object_var->pp_instance());
     61   if (found_instance == instance_map_.end()) {
     62     NOTREACHED() << "NPObjectVar has invalid instance.";
     63     return;
     64   }
     65   NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get();
     66 
     67   NPObjectToNPObjectVarMap::iterator found_object =
     68       np_object_map->find(object_var->np_object());
     69   if (found_object == np_object_map->end()) {
     70     NOTREACHED() << "NPObjectVar not registered.";
     71     return;
     72   }
     73   if (found_object->second != object_var) {
     74     NOTREACHED() << "NPObjectVar doesn't match.";
     75     return;
     76   }
     77   np_object_map->erase(found_object);
     78 }
     79 
     80 NPObjectVar* HostVarTracker::NPObjectVarForNPObject(PP_Instance instance,
     81                                                     NPObject* np_object) {
     82   CheckThreadingPreconditions();
     83 
     84   InstanceMap::iterator found_instance = instance_map_.find(instance);
     85   if (found_instance == instance_map_.end())
     86     return NULL;  // No such instance.
     87   NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get();
     88 
     89   NPObjectToNPObjectVarMap::iterator found_object =
     90       np_object_map->find(np_object);
     91   if (found_object == np_object_map->end())
     92     return NULL;  // No such object.
     93   return found_object->second;
     94 }
     95 
     96 int HostVarTracker::GetLiveNPObjectVarsForInstance(PP_Instance instance) const {
     97   CheckThreadingPreconditions();
     98 
     99   InstanceMap::const_iterator found = instance_map_.find(instance);
    100   if (found == instance_map_.end())
    101     return 0;
    102   return static_cast<int>(found->second->size());
    103 }
    104 
    105 void HostVarTracker::DidDeleteInstance(PP_Instance instance) {
    106   CheckThreadingPreconditions();
    107 
    108   InstanceMap::iterator found_instance = instance_map_.find(instance);
    109   if (found_instance == instance_map_.end())
    110     return;  // Nothing to do.
    111   NPObjectToNPObjectVarMap* np_object_map = found_instance->second.get();
    112 
    113   // Force delete all var references. ForceReleaseNPObject() will cause
    114   // this object, and potentially others it references, to be removed from
    115   // |np_object_map|.
    116   while (!np_object_map->empty()) {
    117     ForceReleaseNPObject(np_object_map->begin()->second);
    118   }
    119 
    120   // Remove the record for this instance since it should be empty.
    121   DCHECK(np_object_map->empty());
    122   instance_map_.erase(found_instance);
    123 }
    124 
    125 void HostVarTracker::ForceReleaseNPObject(ppapi::NPObjectVar* object_var) {
    126   object_var->InstanceDeleted();
    127   VarMap::iterator iter = live_vars_.find(object_var->GetExistingVarID());
    128   if (iter == live_vars_.end()) {
    129     NOTREACHED();
    130     return;
    131   }
    132   iter->second.ref_count = 0;
    133   DCHECK(iter->second.track_with_no_reference_count == 0);
    134   DeleteObjectInfoIfNecessary(iter);
    135 }
    136 
    137 int HostVarTracker::TrackSharedMemoryHandle(PP_Instance instance,
    138                                             base::SharedMemoryHandle handle,
    139                                             uint32 size_in_bytes) {
    140   SharedMemoryMapEntry entry;
    141   entry.instance = instance;
    142   entry.handle = handle;
    143   entry.size_in_bytes = size_in_bytes;
    144 
    145   // Find a free id for our map.
    146   while (shared_memory_map_.find(last_shared_memory_map_id_) !=
    147          shared_memory_map_.end()) {
    148     ++last_shared_memory_map_id_;
    149   }
    150   shared_memory_map_[last_shared_memory_map_id_] = entry;
    151   return last_shared_memory_map_id_;
    152 }
    153 
    154 bool HostVarTracker::StopTrackingSharedMemoryHandle(
    155     int id,
    156     PP_Instance instance,
    157     base::SharedMemoryHandle* handle,
    158     uint32* size_in_bytes) {
    159   SharedMemoryMap::iterator it = shared_memory_map_.find(id);
    160   if (it == shared_memory_map_.end())
    161     return false;
    162   if (it->second.instance != instance)
    163     return false;
    164 
    165   *handle = it->second.handle;
    166   *size_in_bytes = it->second.size_in_bytes;
    167   shared_memory_map_.erase(it);
    168   return true;
    169 }
    170 
    171 }  // namespace content
    172