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 "ppapi/proxy/plugin_resource_tracker.h"
6
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"
16
17namespace ppapi {
18namespace proxy {
19
20PluginResourceTracker::PluginResourceTracker() : ResourceTracker(THREAD_SAFE) {
21  UseOddResourceValueInDebugMode();
22}
23
24PluginResourceTracker::~PluginResourceTracker() {
25}
26
27PP_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())
31    return 0;
32  return found->second;
33}
34
35PP_Resource PluginResourceTracker::AddResource(Resource* object) {
36  // If there's a HostResource, it must not be added twice.
37  DCHECK(!object->host_resource().host_resource() ||
38         (host_resource_map_.find(object->host_resource()) ==
39          host_resource_map_.end()));
40
41  PP_Resource ret = ResourceTracker::AddResource(object);
42
43  // Some resources are plugin-only, so they don't have a host resource.
44  if (object->host_resource().host_resource())
45    host_resource_map_.insert(std::make_pair(object->host_resource(), ret));
46  return ret;
47}
48
49void PluginResourceTracker::RemoveResource(Resource* object) {
50  ResourceTracker::RemoveResource(object);
51
52  if (!object->host_resource().is_null()) {
53    // The host_resource will be NULL for proxy-only resources, which we
54    // obviously don't need to tell the host about.
55    DCHECK(host_resource_map_.find(object->host_resource()) !=
56           host_resource_map_.end());
57    host_resource_map_.erase(object->host_resource());
58
59    PluginDispatcher* dispatcher =
60        PluginDispatcher::GetForInstance(object->pp_instance());
61    if (dispatcher) {
62      // The dispatcher can be NULL if the plugin held on to a resource after
63      // the instance was destroyed. In that case the browser-side resource has
64      // already been freed correctly on the browser side.
65      dispatcher->Send(new PpapiHostMsg_PPBCore_ReleaseResource(
66          API_ID_PPB_CORE, object->host_resource()));
67    }
68  }
69}
70
71}  // namespace proxy
72}  // namespace ppapi
73