OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_ | 5 #ifndef PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_ |
6 #define PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_ | 6 #define PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_ |
7 | 7 |
8 #include <map> | 8 #include <map> |
9 #include <string> | 9 #include <string> |
10 | 10 |
| 11 #include "ipc/ipc_channel.h" |
11 #include "ppapi/c/pp_stdint.h" | 12 #include "ppapi/c/pp_stdint.h" |
12 #include "ppapi/c/pp_var.h" | 13 #include "ppapi/c/pp_var.h" |
13 | 14 |
14 struct PPB_Var; | 15 struct PPB_Var; |
15 | 16 |
| 17 template<typename T> struct DefaultSingletonTraits; |
| 18 |
16 namespace pp { | 19 namespace pp { |
17 namespace proxy { | 20 namespace proxy { |
18 | 21 |
19 class PluginDispatcher; | 22 // Tracks live strings and objects in the plugin process. |
20 | 23 // |
21 // Tracks live strings and objects in the plugin process. We maintain our own | 24 // This object maintains its own object IDs that are used by the plugin. These |
22 // reference count for these objects. In the case of JS objects, we maintain | 25 // IDs can be mapped to the renderer that created them, and that renderer's ID. |
23 // a single ref in the renderer process whenever we have a nonzero refcount | 26 // This way, we can maintain multiple renderers each giving us objects, and the |
24 // in the plugin process. This allows AddRef and Release to not initiate too | 27 // plugin can work with them using a uniform set of unique IDs. |
25 // much IPC chat. | 28 // |
| 29 // We maintain our own reference count for objects. a single ref in the |
| 30 // renderer process whenever we have a nonzero refcount in the plugin process. |
| 31 // This allows AddRef and Release to not initiate too much IPC chat. |
| 32 // |
| 33 // In addition to the local reference count, we also maintain "tracked objects" |
| 34 // which are objects that the plugin is aware of, but doesn't hold a reference |
| 35 // to. This will happen when the plugin is passed an object as an argument from |
| 36 // the host (renderer) but where a reference is not passed. |
26 class PluginVarTracker { | 37 class PluginVarTracker { |
27 public: | 38 public: |
28 // You must call Init() after creation to set up the correct interfaces. We | 39 typedef int64_t VarID; |
29 // do this to avoid having to depend on the dispatcher in the constructor, | |
30 // which is probably just being created from our constructor. | |
31 PluginVarTracker(PluginDispatcher* dispatcher); | |
32 | 40 |
33 ~PluginVarTracker(); | 41 // This uses the PluginDispatcher to identify the source of vars so that |
| 42 // the proper messages can be sent back. However, since all we need is the |
| 43 // ability to send messages, we can always use the Sender base class of |
| 44 // Dispatcher in this class, which makes it easy to unit test. |
| 45 typedef IPC::Channel::Sender Sender; |
34 | 46 |
35 // Must be called after construction. | 47 // Returns the global var tracker for the plugin object. |
36 void Init(); | 48 static PluginVarTracker* GetInstance(); |
37 | 49 |
38 // Allocates a string and returns the ID of it. The refcount will be 1. | 50 // Allocates a string and returns the ID of it. The refcount will be 1. |
39 int64_t MakeString(const std::string& str); | 51 VarID MakeString(const std::string& str); |
40 int64_t MakeString(const char* str, uint32_t len); | 52 VarID MakeString(const char* str, uint32_t len); |
41 | 53 |
42 // Returns the string associated with the given string var. The var must be | 54 // Returns the string associated with the given string var. The var must be |
43 // of type string and must be valid or this function will crash. | 55 // of type string and must be valid or this function will crash. |
44 std::string GetString(const PP_Var& var) const; | 56 std::string GetString(const PP_Var& plugin_var) const; |
45 | 57 |
46 // Returns a pointer to the given string if it exists, or NULL if the var | 58 // Returns a pointer to the given string if it exists, or NULL if the var |
47 // isn't a string var. | 59 // isn't a string var. |
48 const std::string* GetExistingString(const PP_Var& var) const; | 60 const std::string* GetExistingString(const PP_Var& plugin_var) const; |
49 | 61 |
50 void AddRef(const PP_Var& var); | 62 void AddRef(const PP_Var& plugin_var); |
51 void Release(const PP_Var& var); | 63 void Release(const PP_Var& plugin_var); |
52 | 64 |
53 // Manages tracking for receiving a VARTYPE_OBJECT from the remote side | 65 // Manages tracking for receiving a VARTYPE_OBJECT from the remote side |
54 // (either the plugin or the renderer) that has already had its reference | 66 // (either the plugin or the renderer) that has already had its reference |
55 // count incremented on behalf of the caller. | 67 // count incremented on behalf of the caller. |
56 void ReceiveObjectPassRef(const PP_Var& var); | 68 PP_Var ReceiveObjectPassRef(const PP_Var& var, Sender* channel); |
| 69 |
| 70 PP_Var TrackObjectWithNoReference(const PP_Var& host_var, |
| 71 Sender* channel); |
| 72 void StopTrackingObjectWithNoReference(const PP_Var& plugin_var); |
| 73 |
| 74 // Returns the host var for the corresponding plugin object var. The object |
| 75 // should be a VARTYPE_OBJECT |
| 76 PP_Var GetHostObject(const PP_Var& plugin_object) const; |
| 77 |
| 78 // Retrieves the internal reference counts for testing. Returns 0 if we |
| 79 // know about the object but the corresponding value is 0, or -1 if the |
| 80 // given object ID isn't in our map. |
| 81 int GetRefCountForObject(const PP_Var& plugin_object); |
| 82 int GetTrackedWithNoReferenceCountForObject(const PP_Var& plugin_object); |
57 | 83 |
58 private: | 84 private: |
| 85 friend struct DefaultSingletonTraits<PluginVarTracker>; |
| 86 |
| 87 // Represents a var as received from the host. |
| 88 struct HostVar { |
| 89 HostVar(Sender* s, int64_t i); |
| 90 |
| 91 bool operator<(const HostVar& other) const; |
| 92 |
| 93 // The host that sent us this object. This is used so we know how to send |
| 94 // back requests on this object. |
| 95 Sender* channel; |
| 96 |
| 97 // The object ID that the host generated to identify the object. This is |
| 98 // unique only within that host: different hosts could give us different |
| 99 // objects with the same ID. |
| 100 VarID host_object_id; |
| 101 }; |
| 102 |
| 103 // The information associated with a var object in the plugin. |
| 104 struct PluginVarInfo { |
| 105 PluginVarInfo(const HostVar& host_var); |
| 106 |
| 107 // Maps back to the original var in the host. |
| 108 HostVar host_var; |
| 109 |
| 110 // Explicit reference count. This value is affected by the renderer calling |
| 111 // AddRef and Release. A nonzero value here is represented by a single |
| 112 // reference in the host on our behalf (this reduces IPC traffic). |
| 113 int32_t ref_count; |
| 114 |
| 115 // Tracked object count (see class comment above). |
| 116 // |
| 117 // "TrackObjectWithNoReference" might be called recursively in rare cases. |
| 118 // For example, say the host calls a plugin function with an object as an |
| 119 // argument, and in response, the plugin calls a host function that then |
| 120 // calls another (or the same) plugin function with the same object. |
| 121 // |
| 122 // This value tracks the number of calls to TrackObjectWithNoReference so |
| 123 // we know when we can stop tracking this object. |
| 124 int32_t track_with_no_reference_count; |
| 125 }; |
| 126 |
| 127 typedef std::map<int64_t, PluginVarInfo> PluginVarInfoMap; |
| 128 |
| 129 PluginVarTracker(); |
| 130 ~PluginVarTracker(); |
| 131 |
59 // Sends an addref or release message to the browser for the given object ID. | 132 // Sends an addref or release message to the browser for the given object ID. |
60 void SendAddRefObjectMsg(int64_t id); | 133 void SendAddRefObjectMsg(const HostVar& host_var); |
61 void SendReleaseObjectMsg(int64_t id); | 134 void SendReleaseObjectMsg(const HostVar& host_var); |
62 | 135 |
63 PluginDispatcher* dispatcher_; | 136 PluginVarInfoMap::iterator FindOrMakePluginVarFromHostVar( |
| 137 const PP_Var& var, |
| 138 Sender* channel); |
64 | 139 |
65 // Tracks object references to the reference count of that object on the | 140 // Checks the reference counds of the given plugin var info and removes the |
66 // plugin side. | 141 // tracking information if necessary. We're done with the object when its |
67 typedef std::map<int64_t, int> ObjectRefCount; | 142 // explicit reference count and its "tracked with no reference" count both |
68 ObjectRefCount object_ref_count_; | 143 // reach zero. |
| 144 void DeletePluginVarInfoIfNecessary(PluginVarInfoMap::iterator iter); |
| 145 |
| 146 // Tracks all information about plugin vars. |
| 147 PluginVarInfoMap plugin_var_info_; |
| 148 |
| 149 // Maps host vars to plugin vars. This allows us to know if we've previously |
| 150 // seen a host var and re-use the information. |
| 151 typedef std::map<HostVar, VarID> HostVarToPluginVarMap; |
| 152 HostVarToPluginVarMap host_var_to_plugin_var_; |
| 153 |
| 154 // The last plugin object ID we've handed out. This must be unique for the |
| 155 // process. |
| 156 VarID last_plugin_object_id_; |
69 }; | 157 }; |
70 | 158 |
71 } // namespace proxy | 159 } // namespace proxy |
72 } // namespace pp | 160 } // namespace pp |
73 | 161 |
74 #endif // PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_ | 162 #endif // PPAPI_PROXY_PLUGIN_VAR_TRACKER_H_ |
OLD | NEW |