blob: 162f3f8fbd179190433fb6a965986618074ded1e [file] [log] [blame]
[email protected]c2932f5e2010-11-03 03:22:331// Copyright (c) 2010 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 "ppapi/proxy/plugin_resource_tracker.h"
6
7#include "base/logging.h"
[email protected]4614f192011-01-21 00:26:438#include "base/singleton.h"
[email protected]c2932f5e2010-11-03 03:22:339#include "ppapi/proxy/plugin_dispatcher.h"
10#include "ppapi/proxy/ppapi_messages.h"
11#include "ppapi/proxy/plugin_resource.h"
12#include "ppapi/proxy/serialized_var.h"
13
14namespace pp {
15namespace proxy {
16
[email protected]f24448db2011-01-27 20:40:3917namespace {
18
19// When non-NULL, this object overrides the ResourceTrackerSingleton.
20PluginResourceTracker* g_resource_tracker_override = NULL;
21
22} // namespace
23
[email protected]c2932f5e2010-11-03 03:22:3324PluginResourceTracker::ResourceInfo::ResourceInfo() : ref_count(0) {
25}
26
27PluginResourceTracker::ResourceInfo::ResourceInfo(int rc,
28 linked_ptr<PluginResource> r)
29 : ref_count(rc),
30 resource(r) {
31}
32
33PluginResourceTracker::ResourceInfo::ResourceInfo(const ResourceInfo& other)
34 : ref_count(other.ref_count),
35 resource(other.resource) {
36}
37
38PluginResourceTracker::ResourceInfo::~ResourceInfo() {
39}
40
41PluginResourceTracker::ResourceInfo&
42PluginResourceTracker::ResourceInfo::operator=(
43 const ResourceInfo& other) {
44 ref_count = other.ref_count;
45 resource = other.resource;
46 return *this;
47}
48
[email protected]f24448db2011-01-27 20:40:3949// Start counting resources at a high number to avoid collisions with vars (to
50// help debugging).
51PluginResourceTracker::PluginResourceTracker()
52 : last_resource_id_(0x00100000) {
[email protected]c2932f5e2010-11-03 03:22:3353}
54
55PluginResourceTracker::~PluginResourceTracker() {
56}
57
[email protected]4614f192011-01-21 00:26:4358// static
[email protected]f24448db2011-01-27 20:40:3959void PluginResourceTracker::SetInstanceForTest(PluginResourceTracker* tracker) {
60 g_resource_tracker_override = tracker;
61}
62
63// static
[email protected]4614f192011-01-21 00:26:4364PluginResourceTracker* PluginResourceTracker::GetInstance() {
[email protected]f24448db2011-01-27 20:40:3965 if (g_resource_tracker_override)
66 return g_resource_tracker_override;
[email protected]4614f192011-01-21 00:26:4367 return Singleton<PluginResourceTracker>::get();
68}
69
[email protected]c2932f5e2010-11-03 03:22:3370PluginResource* PluginResourceTracker::GetResourceObject(
71 PP_Resource pp_resource) {
72 ResourceMap::iterator found = resource_map_.find(pp_resource);
73 if (found == resource_map_.end())
74 return NULL;
75 return found->second.resource.get();
76}
77
[email protected]f24448db2011-01-27 20:40:3978PP_Resource PluginResourceTracker::AddResource(
79 linked_ptr<PluginResource> object) {
80 if (object->host_resource().is_null()) {
81 // Prevent adding null resources or GetResourceObject(0) will return a
82 // valid pointer!
83 NOTREACHED();
84 return 0;
85 }
86
87 PP_Resource plugin_resource = ++last_resource_id_;
88 DCHECK(resource_map_.find(plugin_resource) == resource_map_.end());
89 resource_map_[plugin_resource] = ResourceInfo(1, object);
90 host_resource_map_[object->host_resource()] = plugin_resource;
91 return plugin_resource;
[email protected]c2932f5e2010-11-03 03:22:3392}
93
94void PluginResourceTracker::AddRefResource(PP_Resource resource) {
[email protected]f24448db2011-01-27 20:40:3995 ResourceMap::iterator found = resource_map_.find(resource);
96 if (found == resource_map_.end()) {
97 NOTREACHED();
98 return;
99 }
100 found->second.ref_count++;
[email protected]c2932f5e2010-11-03 03:22:33101}
102
103void PluginResourceTracker::ReleaseResource(PP_Resource resource) {
104 ReleasePluginResourceRef(resource, true);
105}
106
[email protected]f24448db2011-01-27 20:40:39107PP_Resource PluginResourceTracker::PluginResourceForHostResource(
108 const HostResource& resource) const {
109 HostResourceMap::const_iterator found = host_resource_map_.find(resource);
110 if (found == host_resource_map_.end())
111 return 0;
112 return found->second;
[email protected]799d1ab2010-11-09 17:16:28113}
114
[email protected]c2932f5e2010-11-03 03:22:33115void PluginResourceTracker::ReleasePluginResourceRef(
116 const PP_Resource& resource,
117 bool notify_browser_on_release) {
118 ResourceMap::iterator found = resource_map_.find(resource);
119 if (found == resource_map_.end())
120 return;
121 found->second.ref_count--;
122 if (found->second.ref_count == 0) {
[email protected]f24448db2011-01-27 20:40:39123 PluginResource* plugin_resource = found->second.resource.get();
[email protected]4614f192011-01-21 00:26:43124 if (notify_browser_on_release)
[email protected]f24448db2011-01-27 20:40:39125 SendReleaseResourceToHost(resource, plugin_resource);
126 host_resource_map_.erase(plugin_resource->host_resource());
[email protected]c2932f5e2010-11-03 03:22:33127 resource_map_.erase(found);
128 }
129}
130
[email protected]4614f192011-01-21 00:26:43131void PluginResourceTracker::SendReleaseResourceToHost(
132 PP_Resource resource_id,
133 PluginResource* resource) {
134 PluginDispatcher* dispatcher =
135 PluginDispatcher::GetForInstance(resource->instance());
136 if (dispatcher) {
137 dispatcher->Send(new PpapiHostMsg_PPBCore_ReleaseResource(
[email protected]f24448db2011-01-27 20:40:39138 INTERFACE_ID_PPB_CORE, resource->host_resource()));
[email protected]4614f192011-01-21 00:26:43139 } else {
140 NOTREACHED();
141 }
142}
143
[email protected]c2932f5e2010-11-03 03:22:33144} // namespace proxy
145} // namespace pp