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