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.
5 #include "content/renderer/pepper/host_var_tracker.h"
7 #include "base/logging.h"
8 #include "content/renderer/pepper/host_array_buffer_var.h"
9 #include "content/renderer/pepper/host_resource_var.h"
10 #include "content/renderer/pepper/npobject_var.h"
11 #include "content/renderer/pepper/pepper_plugin_instance_impl.h"
12 #include "ppapi/c/pp_var.h"
14 using ppapi::ArrayBufferVar
;
15 using ppapi::NPObjectVar
;
19 HostVarTracker::HostVarTracker()
20 : VarTracker(SINGLE_THREADED
), last_shared_memory_map_id_(0) {}
22 HostVarTracker::~HostVarTracker() {}
24 ArrayBufferVar
* HostVarTracker::CreateArrayBuffer(uint32 size_in_bytes
) {
25 return new HostArrayBufferVar(size_in_bytes
);
28 ArrayBufferVar
* HostVarTracker::CreateShmArrayBuffer(
30 base::SharedMemoryHandle handle
) {
31 return new HostArrayBufferVar(size_in_bytes
, handle
);
34 void HostVarTracker::AddNPObjectVar(NPObjectVar
* object_var
) {
35 CheckThreadingPreconditions();
37 InstanceMap::iterator found_instance
=
38 instance_map_
.find(object_var
->pp_instance());
39 if (found_instance
== instance_map_
.end()) {
40 // Lazily create the instance map.
41 DCHECK(object_var
->pp_instance() != 0);
43 instance_map_
.insert(std::make_pair(
44 object_var
->pp_instance(),
45 linked_ptr
<NPObjectToNPObjectVarMap
>(
46 new NPObjectToNPObjectVarMap
))).first
;
48 NPObjectToNPObjectVarMap
* np_object_map
= found_instance
->second
.get();
50 DCHECK(np_object_map
->find(object_var
->np_object()) == np_object_map
->end())
51 << "NPObjectVar already in map";
52 np_object_map
->insert(std::make_pair(object_var
->np_object(), object_var
));
55 void HostVarTracker::RemoveNPObjectVar(NPObjectVar
* object_var
) {
56 CheckThreadingPreconditions();
58 InstanceMap::iterator found_instance
=
59 instance_map_
.find(object_var
->pp_instance());
60 if (found_instance
== instance_map_
.end()) {
61 NOTREACHED() << "NPObjectVar has invalid instance.";
64 NPObjectToNPObjectVarMap
* np_object_map
= found_instance
->second
.get();
66 NPObjectToNPObjectVarMap::iterator found_object
=
67 np_object_map
->find(object_var
->np_object());
68 if (found_object
== np_object_map
->end()) {
69 NOTREACHED() << "NPObjectVar not registered.";
72 if (found_object
->second
!= object_var
) {
73 NOTREACHED() << "NPObjectVar doesn't match.";
76 np_object_map
->erase(found_object
);
79 NPObjectVar
* HostVarTracker::NPObjectVarForNPObject(PP_Instance instance
,
80 NPObject
* np_object
) {
81 CheckThreadingPreconditions();
83 InstanceMap::iterator found_instance
= instance_map_
.find(instance
);
84 if (found_instance
== instance_map_
.end())
85 return NULL
; // No such instance.
86 NPObjectToNPObjectVarMap
* np_object_map
= found_instance
->second
.get();
88 NPObjectToNPObjectVarMap::iterator found_object
=
89 np_object_map
->find(np_object
);
90 if (found_object
== np_object_map
->end())
91 return NULL
; // No such object.
92 return found_object
->second
;
95 int HostVarTracker::GetLiveNPObjectVarsForInstance(PP_Instance instance
) const {
96 CheckThreadingPreconditions();
98 InstanceMap::const_iterator found
= instance_map_
.find(instance
);
99 if (found
== instance_map_
.end())
101 return static_cast<int>(found
->second
->size());
104 PP_Var
HostVarTracker::MakeResourcePPVarFromMessage(
105 PP_Instance instance
,
106 const IPC::Message
& creation_message
,
107 int pending_renderer_id
,
108 int pending_browser_id
) {
109 // On the host side, the creation message is ignored when creating a resource.
110 // Therefore, a call to this function indicates a null resource. Return the
112 return MakeResourcePPVar(0);
115 ppapi::ResourceVar
* HostVarTracker::MakeResourceVar(PP_Resource pp_resource
) {
116 return new HostResourceVar(pp_resource
);
119 void HostVarTracker::DidDeleteInstance(PP_Instance instance
) {
120 CheckThreadingPreconditions();
122 InstanceMap::iterator found_instance
= instance_map_
.find(instance
);
123 if (found_instance
== instance_map_
.end())
124 return; // Nothing to do.
125 NPObjectToNPObjectVarMap
* np_object_map
= found_instance
->second
.get();
127 // Force delete all var references. ForceReleaseNPObject() will cause
128 // this object, and potentially others it references, to be removed from
130 while (!np_object_map
->empty()) {
131 ForceReleaseNPObject(np_object_map
->begin()->second
);
134 // Remove the record for this instance since it should be empty.
135 DCHECK(np_object_map
->empty());
136 instance_map_
.erase(found_instance
);
139 void HostVarTracker::ForceReleaseNPObject(ppapi::NPObjectVar
* object_var
) {
140 object_var
->InstanceDeleted();
141 VarMap::iterator iter
= live_vars_
.find(object_var
->GetExistingVarID());
142 if (iter
== live_vars_
.end()) {
146 iter
->second
.ref_count
= 0;
147 DCHECK(iter
->second
.track_with_no_reference_count
== 0);
148 DeleteObjectInfoIfNecessary(iter
);
151 int HostVarTracker::TrackSharedMemoryHandle(PP_Instance instance
,
152 base::SharedMemoryHandle handle
,
153 uint32 size_in_bytes
) {
154 SharedMemoryMapEntry entry
;
155 entry
.instance
= instance
;
156 entry
.handle
= handle
;
157 entry
.size_in_bytes
= size_in_bytes
;
159 // Find a free id for our map.
160 while (shared_memory_map_
.find(last_shared_memory_map_id_
) !=
161 shared_memory_map_
.end()) {
162 ++last_shared_memory_map_id_
;
164 shared_memory_map_
[last_shared_memory_map_id_
] = entry
;
165 return last_shared_memory_map_id_
;
168 bool HostVarTracker::StopTrackingSharedMemoryHandle(
170 PP_Instance instance
,
171 base::SharedMemoryHandle
* handle
,
172 uint32
* size_in_bytes
) {
173 SharedMemoryMap::iterator it
= shared_memory_map_
.find(id
);
174 if (it
== shared_memory_map_
.end())
176 if (it
->second
.instance
!= instance
)
179 *handle
= it
->second
.handle
;
180 *size_in_bytes
= it
->second
.size_in_bytes
;
181 shared_memory_map_
.erase(it
);
185 } // namespace content