summaryrefslogtreecommitdiffstats
path: root/ppapi/proxy/plugin_var_tracker.h
diff options
context:
space:
mode:
authorbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-21 00:26:43 +0000
committerbrettw@chromium.org <brettw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-01-21 00:26:43 +0000
commit4614f1974881ecfd0a0118683bac628c6128c2a9 (patch)
treec69836459560dd8003f7e18ca554f2e1d7f79b4d /ppapi/proxy/plugin_var_tracker.h
parentb8e6654fb91108033580f510e2d411093936fc2f (diff)
downloadchromium_src-4614f1974881ecfd0a0118683bac628c6128c2a9.zip
chromium_src-4614f1974881ecfd0a0118683bac628c6128c2a9.tar.gz
chromium_src-4614f1974881ecfd0a0118683bac628c6128c2a9.tar.bz2
First pass at making the proxy handle multiple renderers. This associates the
instance with resources and has most callers retrieve the dispatcher according to the appropriate instance. This isn't hooked up to anything yet. This changes some PPB_Flash interface methods to use PP_Bool. The most challenging part of the change is in the plugin_var_tracker which now needs to track which dispatcher each var object came from, and remap var IDs since each renderer will be generating var IDs in its own space, which will likely overlap. A similar system will need to be done for resources which is not implemented yet. I added some null checks in audio_impl because audio_ can be NULL in some cases when using the trusted API. I discovered this when testing NaCl for this patch. Review URL: http://codereview.chromium.org/6282007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@72053 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/proxy/plugin_var_tracker.h')
-rw-r--r--ppapi/proxy/plugin_var_tracker.h148
1 files changed, 118 insertions, 30 deletions
diff --git a/ppapi/proxy/plugin_var_tracker.h b/ppapi/proxy/plugin_var_tracker.h
index 9a1b9ab..4d6c49c 100644
--- a/ppapi/proxy/plugin_var_tracker.h
+++ b/ppapi/proxy/plugin_var_tracker.h
@@ -8,64 +8,152 @@
#include <map>
#include <string>
+#include "ipc/ipc_channel.h"
#include "ppapi/c/pp_stdint.h"
#include "ppapi/c/pp_var.h"
struct PPB_Var;
+template<typename T> struct DefaultSingletonTraits;
+
namespace pp {
namespace proxy {
-class PluginDispatcher;
-
-// Tracks live strings and objects in the plugin process. We maintain our own
-// reference count for these objects. In the case of JS objects, we maintain
-// a single ref in the renderer process whenever we have a nonzero refcount
-// in the plugin process. This allows AddRef and Release to not initiate too
-// much IPC chat.
+// Tracks live strings and objects in the plugin process.
+//
+// This object maintains its own object IDs that are used by the plugin. These
+// IDs can be mapped to the renderer that created them, and that renderer's ID.
+// This way, we can maintain multiple renderers each giving us objects, and the
+// plugin can work with them using a uniform set of unique IDs.
+//
+// We maintain our own reference count for objects. a single ref in the
+// renderer process whenever we have a nonzero refcount in the plugin process.
+// This allows AddRef and Release to not initiate too much IPC chat.
+//
+// In addition to the local reference count, we also maintain "tracked objects"
+// which are objects that the plugin is aware of, but doesn't hold a reference
+// to. This will happen when the plugin is passed an object as an argument from
+// the host (renderer) but where a reference is not passed.
class PluginVarTracker {
public:
- // You must call Init() after creation to set up the correct interfaces. We
- // do this to avoid having to depend on the dispatcher in the constructor,
- // which is probably just being created from our constructor.
- PluginVarTracker(PluginDispatcher* dispatcher);
+ typedef int64_t VarID;
- ~PluginVarTracker();
+ // This uses the PluginDispatcher to identify the source of vars so that
+ // the proper messages can be sent back. However, since all we need is the
+ // ability to send messages, we can always use the Sender base class of
+ // Dispatcher in this class, which makes it easy to unit test.
+ typedef IPC::Channel::Sender Sender;
- // Must be called after construction.
- void Init();
+ // Returns the global var tracker for the plugin object.
+ static PluginVarTracker* GetInstance();
// Allocates a string and returns the ID of it. The refcount will be 1.
- int64_t MakeString(const std::string& str);
- int64_t MakeString(const char* str, uint32_t len);
+ VarID MakeString(const std::string& str);
+ VarID MakeString(const char* str, uint32_t len);
// Returns the string associated with the given string var. The var must be
// of type string and must be valid or this function will crash.
- std::string GetString(const PP_Var& var) const;
+ std::string GetString(const PP_Var& plugin_var) const;
// Returns a pointer to the given string if it exists, or NULL if the var
// isn't a string var.
- const std::string* GetExistingString(const PP_Var& var) const;
+ const std::string* GetExistingString(const PP_Var& plugin_var) const;
- void AddRef(const PP_Var& var);
- void Release(const PP_Var& var);
+ void AddRef(const PP_Var& plugin_var);
+ void Release(const PP_Var& plugin_var);
// Manages tracking for receiving a VARTYPE_OBJECT from the remote side
// (either the plugin or the renderer) that has already had its reference
// count incremented on behalf of the caller.
- void ReceiveObjectPassRef(const PP_Var& var);
+ PP_Var ReceiveObjectPassRef(const PP_Var& var, Sender* channel);
- private:
- // Sends an addref or release message to the browser for the given object ID.
- void SendAddRefObjectMsg(int64_t id);
- void SendReleaseObjectMsg(int64_t id);
+ PP_Var TrackObjectWithNoReference(const PP_Var& host_var,
+ Sender* channel);
+ void StopTrackingObjectWithNoReference(const PP_Var& plugin_var);
- PluginDispatcher* dispatcher_;
+ // Returns the host var for the corresponding plugin object var. The object
+ // should be a VARTYPE_OBJECT
+ PP_Var GetHostObject(const PP_Var& plugin_object) const;
- // Tracks object references to the reference count of that object on the
- // plugin side.
- typedef std::map<int64_t, int> ObjectRefCount;
- ObjectRefCount object_ref_count_;
+ // Retrieves the internal reference counts for testing. Returns 0 if we
+ // know about the object but the corresponding value is 0, or -1 if the
+ // given object ID isn't in our map.
+ int GetRefCountForObject(const PP_Var& plugin_object);
+ int GetTrackedWithNoReferenceCountForObject(const PP_Var& plugin_object);
+
+ private:
+ friend struct DefaultSingletonTraits<PluginVarTracker>;
+
+ // Represents a var as received from the host.
+ struct HostVar {
+ HostVar(Sender* s, int64_t i);
+
+ bool operator<(const HostVar& other) const;
+
+ // The host that sent us this object. This is used so we know how to send
+ // back requests on this object.
+ Sender* channel;
+
+ // The object ID that the host generated to identify the object. This is
+ // unique only within that host: different hosts could give us different
+ // objects with the same ID.
+ VarID host_object_id;
+ };
+
+ // The information associated with a var object in the plugin.
+ struct PluginVarInfo {
+ PluginVarInfo(const HostVar& host_var);
+
+ // Maps back to the original var in the host.
+ HostVar host_var;
+
+ // Explicit reference count. This value is affected by the renderer calling
+ // AddRef and Release. A nonzero value here is represented by a single
+ // reference in the host on our behalf (this reduces IPC traffic).
+ int32_t ref_count;
+
+ // Tracked object count (see class comment above).
+ //
+ // "TrackObjectWithNoReference" might be called recursively in rare cases.
+ // For example, say the host calls a plugin function with an object as an
+ // argument, and in response, the plugin calls a host function that then
+ // calls another (or the same) plugin function with the same object.
+ //
+ // This value tracks the number of calls to TrackObjectWithNoReference so
+ // we know when we can stop tracking this object.
+ int32_t track_with_no_reference_count;
+ };
+
+ typedef std::map<int64_t, PluginVarInfo> PluginVarInfoMap;
+
+ PluginVarTracker();
+ ~PluginVarTracker();
+
+ // Sends an addref or release message to the browser for the given object ID.
+ void SendAddRefObjectMsg(const HostVar& host_var);
+ void SendReleaseObjectMsg(const HostVar& host_var);
+
+ PluginVarInfoMap::iterator FindOrMakePluginVarFromHostVar(
+ const PP_Var& var,
+ Sender* channel);
+
+ // Checks the reference counds of the given plugin var info and removes the
+ // tracking information if necessary. We're done with the object when its
+ // explicit reference count and its "tracked with no reference" count both
+ // reach zero.
+ void DeletePluginVarInfoIfNecessary(PluginVarInfoMap::iterator iter);
+
+ // Tracks all information about plugin vars.
+ PluginVarInfoMap plugin_var_info_;
+
+ // Maps host vars to plugin vars. This allows us to know if we've previously
+ // seen a host var and re-use the information.
+ typedef std::map<HostVar, VarID> HostVarToPluginVarMap;
+ HostVarToPluginVarMap host_var_to_plugin_var_;
+
+ // The last plugin object ID we've handed out. This must be unique for the
+ // process.
+ VarID last_plugin_object_id_;
};
} // namespace proxy