diff options
author | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-08 20:22:02 +0000 |
---|---|---|
committer | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-06-08 20:22:02 +0000 |
commit | 0925622c1495325dfe3d3b25273f4439361936bc (patch) | |
tree | d84e13ff0c89660b3c0353095a59e296f3582ccb /ppapi/proxy/plugin_var_tracker.cc | |
parent | 67b85487bf8e376297a8cc0cbf5fa3f0fa1d078b (diff) | |
download | chromium_src-0925622c1495325dfe3d3b25273f4439361936bc.zip chromium_src-0925622c1495325dfe3d3b25273f4439361936bc.tar.gz chromium_src-0925622c1495325dfe3d3b25273f4439361936bc.tar.bz2 |
Proxy PPB_Var, fix o-o-p string var id tracking.
Note this doesn't need to use IPC at all, so it's a little strange.
Made test for pp::Var/PPB_Var that does only strings (copied from test_var_deprecated.cc). Fixed string var tracking so test can pass out-of-process (aside from invalid UTF8 checking, which is still not implemented o-o-p).
BUG=85236
TEST=test_var.cc, run tests manually out-of-process.
Review URL: http://codereview.chromium.org/6995083
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@88384 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/proxy/plugin_var_tracker.cc')
-rw-r--r-- | ppapi/proxy/plugin_var_tracker.cc | 81 |
1 files changed, 43 insertions, 38 deletions
diff --git a/ppapi/proxy/plugin_var_tracker.cc b/ppapi/proxy/plugin_var_tracker.cc index 151fd2b..5734f96 100644 --- a/ppapi/proxy/plugin_var_tracker.cc +++ b/ppapi/proxy/plugin_var_tracker.cc @@ -19,28 +19,6 @@ namespace { // When non-NULL, this object overrides the VarTrackerSingleton. PluginVarTracker* var_tracker_override = NULL; -class RefCountedString : public base::RefCounted<RefCountedString> { - public: - RefCountedString() { - } - RefCountedString(const std::string& str) : value_(str) { - } - RefCountedString(const char* data, size_t len) - : value_(data, len) { - } - - const std::string& value() const { return value_; } - - private: - std::string value_; -}; - -// When running in the plugin, this will convert the string ID to the object -// using casting. No validity checking is done. -RefCountedString* PluginStringFromID(PluginVarTracker::VarID id) { - return reinterpret_cast<RefCountedString*>(static_cast<intptr_t>(id)); -} - } // namespace PluginVarTracker::HostVar::HostVar(PluginDispatcher* d, VarID i) @@ -62,7 +40,7 @@ PluginVarTracker::PluginVarInfo::PluginVarInfo(const HostVar& host_var) track_with_no_reference_count(0) { } -PluginVarTracker::PluginVarTracker() : last_plugin_object_id_(0) { +PluginVarTracker::PluginVarTracker() : last_plugin_var_id_(0) { } PluginVarTracker::~PluginVarTracker() { @@ -81,33 +59,45 @@ PluginVarTracker* PluginVarTracker::GetInstance() { } PluginVarTracker::VarID PluginVarTracker::MakeString(const std::string& str) { - RefCountedString* out = new RefCountedString(str); - out->AddRef(); - return static_cast<VarID>(reinterpret_cast<intptr_t>(out)); + return MakeString(str.c_str(), str.length()); } PluginVarTracker::VarID PluginVarTracker::MakeString(const char* str, uint32_t len) { - RefCountedString* out = new RefCountedString(str, len); - out->AddRef(); - return static_cast<VarID>(reinterpret_cast<intptr_t>(out)); -} - -std::string PluginVarTracker::GetString(const PP_Var& var) const { - return PluginStringFromID(var.value.as_id)->value(); + std::pair<VarIDStringMap::iterator, bool> + iter_success_pair(var_id_to_string_.end(), false); + VarID new_id(0); + RefCountedStringPtr str_ptr(new RefCountedString(str, len)); + // Pick new IDs until one is successfully inserted. This loop is very unlikely + // to ever run a 2nd time, since we have ~2^63 possible IDs to exhaust. + while (!iter_success_pair.second) { + new_id = GetNewVarID(); + iter_success_pair = + var_id_to_string_.insert(VarIDStringMap::value_type(new_id, str_ptr)); + } + iter_success_pair.first->second->AddRef(); + return new_id; } const std::string* PluginVarTracker::GetExistingString( const PP_Var& var) const { if (var.type != PP_VARTYPE_STRING) return NULL; - RefCountedString* str = PluginStringFromID(var.value.as_id); - return &str->value(); + VarIDStringMap::const_iterator found = + var_id_to_string_.find(var.value.as_id); + if (found != var_id_to_string_.end()) + return &found->second->value(); + return NULL; } void PluginVarTracker::AddRef(const PP_Var& var) { if (var.type == PP_VARTYPE_STRING) { - PluginStringFromID(var.value.as_id)->AddRef(); + VarIDStringMap::iterator found = var_id_to_string_.find(var.value.as_id); + if (found == var_id_to_string_.end()) { + NOTREACHED() << "Requesting to addref an unknown string."; + return; + } + found->second->AddRef(); } else if (var.type == PP_VARTYPE_OBJECT && var.value.as_id != 0) { PluginVarInfoMap::iterator found = plugin_var_info_.find(var.value.as_id); if (found == plugin_var_info_.end()) { @@ -131,7 +121,16 @@ void PluginVarTracker::AddRef(const PP_Var& var) { void PluginVarTracker::Release(const PP_Var& var) { if (var.type == PP_VARTYPE_STRING) { - PluginStringFromID(var.value.as_id)->Release(); + VarIDStringMap::iterator found = var_id_to_string_.find(var.value.as_id); + if (found == var_id_to_string_.end()) { + NOTREACHED() << "Requesting to release an unknown string."; + return; + } + found->second->Release(); + // If there is only 1 reference left, it's the map's reference. Erase it + // from the map, which will delete the string. + if (found->second->HasOneRef()) + var_id_to_string_.erase(found); } else if (var.type == PP_VARTYPE_OBJECT) { PluginVarInfoMap::iterator found = plugin_var_info_.find(var.value.as_id); if (found == plugin_var_info_.end()) { @@ -308,7 +307,7 @@ PluginVarTracker::FindOrMakePluginVarFromHostVar(const PP_Var& var, } // Make a new var, adding references to both maps. - VarID new_plugin_var_id = ++last_plugin_object_id_; + VarID new_plugin_var_id = GetNewVarID(); host_var_to_plugin_var_[host_var] = new_plugin_var_id; return plugin_var_info_.insert( std::make_pair(new_plugin_var_id, PluginVarInfo(host_var))).first; @@ -327,5 +326,11 @@ void PluginVarTracker::DeletePluginVarInfoIfNecessary( plugin_var_info_.erase(iter); } +PluginVarTracker::VarID PluginVarTracker::GetNewVarID() { + if (last_plugin_var_id_ == std::numeric_limits<VarID>::max()) + last_plugin_var_id_ = 0; + return ++last_plugin_var_id_; +} + } // namesace proxy } // namespace pp |