summaryrefslogtreecommitdiffstats
path: root/ppapi/shared_impl/resource_tracker.h
blob: e60d8e06237828c318644dd6667101172c4386d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef PPAPI_SHARED_IMPL_RESOURCE_TRACKER_H_
#define PPAPI_SHARED_IMPL_RESOURCE_TRACKER_H_

#include <set>

#include "base/basictypes.h"
#include "base/hash_tables.h"
#include "base/memory/linked_ptr.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/shared_impl/ppapi_shared_export.h"

namespace ppapi {

class Resource;

class PPAPI_SHARED_EXPORT ResourceTracker {
 public:
  ResourceTracker();
  virtual ~ResourceTracker();

  // The returned pointer will be NULL if there is no resource. The reference
  // count of the resource is unaffected.
  Resource* GetResource(PP_Resource res) const;

  void AddRefResource(PP_Resource res);
  void ReleaseResource(PP_Resource res);

  // Notifies the tracker that a new instance has been created. This must be
  // called before creating any resources associated with the instance.
  void DidCreateInstance(PP_Instance instance);

  // Called when an instance is being deleted. All plugin refs for the
  // associated resources will be force freed, and the resources (if they still
  // exist) will be disassociated from the instance.
  void DidDeleteInstance(PP_Instance instance);

  // Returns the number of resources associated with the given instance.
  // Returns 0 if the instance isn't known.
  int GetLiveObjectsForInstance(PP_Instance instance) const;

 protected:
  // This calls AddResource and RemoveResource.
  friend class Resource;

  // Adds the given resource to the tracker, associating it with the instance
  // stored in the resource object. The new resource ID is returned, and the
  // resource will have 0 plugin refcount. This is called by the resource
  // constructor.
  //
  // Returns 0 if the resource could not be added.
  virtual PP_Resource AddResource(Resource* object);

  // The opposite of AddResource, this removes the tracking information for
  // the given resource. It's called from the resource destructor.
  virtual void RemoveResource(Resource* object);

  // Calls LastPluginRefWasDeleted on the given resource object. This is
  // provided because the derived class in webkit/plugins/ppapi needs to
  // perform additional operations at this time.
  virtual void LastPluginRefWasDeleted(Resource* object);

 private:
  typedef std::set<PP_Resource> ResourceSet;

  struct InstanceData {
    // Lists all resources associated with the given instance as non-owning
    // pointers. This allows us to notify those resources that the instance is
    // going away (otherwise, they may crash if they outlive the instance).
    ResourceSet resources;
  };
  typedef base::hash_map<PP_Instance, linked_ptr<InstanceData> > InstanceMap;

  InstanceMap instance_map_;

  // For each PP_Resource, keep the object pointer and a plugin use count.
  // This use count is different then Resource object's RefCount, and is
  // manipulated using this AddRefResource/UnrefResource. When the plugin use
  // count is positive, we keep an extra ref on the Resource on
  // behalf of the plugin. When it drops to 0, we free that ref, keeping
  // the resource in the list.
  //
  // A resource will be in this list as long as the object is alive.
  typedef std::pair<Resource*, int> ResourceAndRefCount;
  typedef base::hash_map<PP_Resource, ResourceAndRefCount> ResourceMap;
  ResourceMap live_resources_;

  int32 last_resource_value_;

  DISALLOW_COPY_AND_ASSIGN(ResourceTracker);
};

}  // namespace ppapi

#endif  // PPAPI_SHARED_IMPL_RESOURCE_TRACKER_H_