summaryrefslogtreecommitdiffstats
path: root/ppapi/proxy/plugin_var_tracker.cc
diff options
context:
space:
mode:
Diffstat (limited to 'ppapi/proxy/plugin_var_tracker.cc')
-rw-r--r--ppapi/proxy/plugin_var_tracker.cc81
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