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 "ppapi/proxy/plugin_resource_tracker.h"
7 #include "base/logging.h"
8 #include "base/memory/singleton.h"
9 #include "ppapi/proxy/plugin_dispatcher.h"
10 #include "ppapi/proxy/plugin_globals.h"
11 #include "ppapi/proxy/ppapi_messages.h"
12 #include "ppapi/proxy/serialized_var.h"
13 #include "ppapi/shared_impl/proxy_lock.h"
14 #include "ppapi/shared_impl/resource.h"
15 #include "ppapi/shared_impl/var.h"
20 PluginResourceTracker::PluginResourceTracker() : ResourceTracker(THREAD_SAFE
) {
21 UseOddResourceValueInDebugMode();
24 PluginResourceTracker::~PluginResourceTracker() {
27 PP_Resource
PluginResourceTracker::PluginResourceForHostResource(
28 const HostResource
& resource
) const {
29 HostResourceMap::const_iterator found
= host_resource_map_
.find(resource
);
30 if (found
== host_resource_map_
.end())
35 void PluginResourceTracker::AbandonResource(PP_Resource res
) {
36 DCHECK(GetResource(res
));
37 bool inserted
= abandoned_resources_
.insert(res
).second
;
43 PP_Resource
PluginResourceTracker::AddResource(Resource
* object
) {
44 // If there's a HostResource, it must not be added twice.
45 DCHECK(!object
->host_resource().host_resource() ||
46 (host_resource_map_
.find(object
->host_resource()) ==
47 host_resource_map_
.end()));
49 PP_Resource ret
= ResourceTracker::AddResource(object
);
51 // Some resources are plugin-only, so they don't have a host resource.
52 if (object
->host_resource().host_resource())
53 host_resource_map_
.insert(std::make_pair(object
->host_resource(), ret
));
57 void PluginResourceTracker::RemoveResource(Resource
* object
) {
58 ResourceTracker::RemoveResource(object
);
60 if (!object
->host_resource().is_null()) {
61 // The host_resource will be NULL for proxy-only resources, which we
62 // obviously don't need to tell the host about.
63 DCHECK(host_resource_map_
.find(object
->host_resource()) !=
64 host_resource_map_
.end());
65 host_resource_map_
.erase(object
->host_resource());
67 bool abandoned
= false;
68 auto it
= abandoned_resources_
.find(object
->pp_resource());
69 if (it
!= abandoned_resources_
.end()) {
71 abandoned_resources_
.erase(it
);
74 PluginDispatcher
* dispatcher
=
75 PluginDispatcher::GetForInstance(object
->pp_instance());
76 if (dispatcher
&& !abandoned
) {
77 // The dispatcher can be NULL if the plugin held on to a resource after
78 // the instance was destroyed. In that case the browser-side resource has
79 // already been freed correctly on the browser side.
80 dispatcher
->Send(new PpapiHostMsg_PPBCore_ReleaseResource(
81 API_ID_PPB_CORE
, object
->host_resource()));