blob: 23514051aecb4a04b9f434079ff47a5d7f2dd0a6 [file] [log] [blame]
[email protected]3890cfff2012-02-29 07:54:181// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]7f8b26b2011-08-18 15:41:012// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef PPAPI_SHARED_IMPL_RESOURCE_TRACKER_H_
6#define PPAPI_SHARED_IMPL_RESOURCE_TRACKER_H_
7
avie029c4132015-12-23 06:45:228#include <stdint.h>
9
[email protected]7f8b26b2011-08-18 15:41:0110#include <set>
11
[email protected]14c1c232013-06-11 17:52:4412#include "base/containers/hash_tables.h"
avie029c4132015-12-23 06:45:2213#include "base/macros.h"
[email protected]7f8b26b2011-08-18 15:41:0114#include "base/memory/linked_ptr.h"
[email protected]b73c6592013-03-30 17:08:1315#include "base/memory/scoped_ptr.h"
[email protected]3890cfff2012-02-29 07:54:1816#include "base/memory/weak_ptr.h"
[email protected]97f79ec02012-09-06 22:03:2717#include "base/threading/thread_checker.h"
18#include "base/threading/thread_checker_impl.h"
[email protected]7f8b26b2011-08-18 15:41:0119#include "ppapi/c/pp_instance.h"
20#include "ppapi/c/pp_resource.h"
[email protected]f0a04c42011-08-26 22:43:2021#include "ppapi/shared_impl/ppapi_shared_export.h"
[email protected]7f8b26b2011-08-18 15:41:0122
23namespace ppapi {
24
25class Resource;
26
[email protected]f0a04c42011-08-26 22:43:2027class PPAPI_SHARED_EXPORT ResourceTracker {
[email protected]7f8b26b2011-08-18 15:41:0128 public:
[email protected]b73c6592013-03-30 17:08:1329 // A SINGLE_THREADED ResourceTracker will use a thread-checker to make sure
30 // it's always invoked on the same thread on which it was constructed. A
31 // THREAD_SAFE ResourceTracker will check that the ProxyLock is held. See
32 // CheckThreadingPreconditions() for more details.
33 enum ThreadMode { SINGLE_THREADED, THREAD_SAFE };
34 explicit ResourceTracker(ThreadMode thread_mode);
[email protected]7f8b26b2011-08-18 15:41:0135 virtual ~ResourceTracker();
36
37 // The returned pointer will be NULL if there is no resource. The reference
38 // count of the resource is unaffected.
39 Resource* GetResource(PP_Resource res) const;
40
[email protected]b8c63032013-08-15 16:28:3341 // Takes a reference on the given resource.
42 // Do not call this method on on the host side for resources backed by a
43 // ResourceHost.
[email protected]7f8b26b2011-08-18 15:41:0144 void AddRefResource(PP_Resource res);
[email protected]b8c63032013-08-15 16:28:3345
46 // Releases a reference on the given resource.
47 // Do not call this method on on the host side for resources backed by a
48 // ResourceHost.
[email protected]7f8b26b2011-08-18 15:41:0149 void ReleaseResource(PP_Resource res);
50
[email protected]7f8b26b2011-08-18 15:41:0151 // Notifies the tracker that a new instance has been created. This must be
52 // called before creating any resources associated with the instance.
53 void DidCreateInstance(PP_Instance instance);
54
55 // Called when an instance is being deleted. All plugin refs for the
56 // associated resources will be force freed, and the resources (if they still
57 // exist) will be disassociated from the instance.
58 void DidDeleteInstance(PP_Instance instance);
59
60 // Returns the number of resources associated with the given instance.
61 // Returns 0 if the instance isn't known.
62 int GetLiveObjectsForInstance(PP_Instance instance) const;
63
64 protected:
65 // This calls AddResource and RemoveResource.
66 friend class Resource;
67
[email protected]b73c6592013-03-30 17:08:1368 // On the host-side, make sure we are called on the right thread. On the
69 // plugin side, make sure we have the proxy lock.
70 void CheckThreadingPreconditions() const;
71
[email protected]3eaf5432013-08-13 19:18:1172 // This method is called by PluginResourceTracker's constructor so that in
73 // debug mode PP_Resources from the plugin process always have odd values
74 // (ignoring the type bits), while PP_Resources from the renderer process have
75 // even values.
76 // This allows us to check that resource refs aren't added or released on the
77 // wrong side.
78 void UseOddResourceValueInDebugMode();
79
[email protected]7f8b26b2011-08-18 15:41:0180 // Adds the given resource to the tracker, associating it with the instance
81 // stored in the resource object. The new resource ID is returned, and the
82 // resource will have 0 plugin refcount. This is called by the resource
83 // constructor.
84 //
85 // Returns 0 if the resource could not be added.
86 virtual PP_Resource AddResource(Resource* object);
87
88 // The opposite of AddResource, this removes the tracking information for
89 // the given resource. It's called from the resource destructor.
90 virtual void RemoveResource(Resource* object);
91
[email protected]97f79ec02012-09-06 22:03:2792 private:
[email protected]28df6a02012-11-08 07:29:4593 // Calls NotifyLastPluginRefWasDeleted on the given resource object and
94 // cancels pending callbacks for the resource.
[email protected]19bb6722012-01-04 22:53:0895 void LastPluginRefWasDeleted(Resource* object);
[email protected]bbf076f12011-08-24 15:19:3796
avie029c4132015-12-23 06:45:2297 int32_t GetNextResourceValue();
[email protected]3eaf5432013-08-13 19:18:1198
99 // In debug mode, checks whether |res| comes from the same resource tracker.
100 bool CanOperateOnResource(PP_Resource res);
101
[email protected]7f8b26b2011-08-18 15:41:01102 typedef std::set<PP_Resource> ResourceSet;
103
104 struct InstanceData {
105 // Lists all resources associated with the given instance as non-owning
106 // pointers. This allows us to notify those resources that the instance is
107 // going away (otherwise, they may crash if they outlive the instance).
108 ResourceSet resources;
109 };
110 typedef base::hash_map<PP_Instance, linked_ptr<InstanceData> > InstanceMap;
111
112 InstanceMap instance_map_;
113
114 // For each PP_Resource, keep the object pointer and a plugin use count.
115 // This use count is different then Resource object's RefCount, and is
116 // manipulated using this AddRefResource/UnrefResource. When the plugin use
117 // count is positive, we keep an extra ref on the Resource on
118 // behalf of the plugin. When it drops to 0, we free that ref, keeping
119 // the resource in the list.
120 //
121 // A resource will be in this list as long as the object is alive.
122 typedef std::pair<Resource*, int> ResourceAndRefCount;
123 typedef base::hash_map<PP_Resource, ResourceAndRefCount> ResourceMap;
124 ResourceMap live_resources_;
125
avie029c4132015-12-23 06:45:22126 int32_t last_resource_value_;
[email protected]7f8b26b2011-08-18 15:41:01127
[email protected]b73c6592013-03-30 17:08:13128 // On the host side, we want to check that we are only called on the main
129 // thread. This is to protect us from accidentally using the tracker from
130 // other threads (especially the IO thread). On the plugin side, the tracker
131 // is protected by the proxy lock and is thread-safe, so this will be NULL.
132 scoped_ptr<base::ThreadChecker> thread_checker_;
[email protected]97f79ec02012-09-06 22:03:27133
[email protected]dcf10632013-10-08 19:23:33134 base::WeakPtrFactory<ResourceTracker> weak_ptr_factory_;
135
[email protected]7f8b26b2011-08-18 15:41:01136 DISALLOW_COPY_AND_ASSIGN(ResourceTracker);
137};
138
139} // namespace ppapi
140
141#endif // PPAPI_SHARED_IMPL_RESOURCE_TRACKER_H_