summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-12 19:38:55 +0000
committerdmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-01-12 19:38:55 +0000
commit73097564b57bad21efbb72e49a0edf0d13e9c249 (patch)
tree3f0e4f402f6fc1252765260241199519a94ce5e3
parenta21d8087f7ca0a8ccf2d07344b7dcfa34d455886 (diff)
downloadchromium_src-73097564b57bad21efbb72e49a0edf0d13e9c249.zip
chromium_src-73097564b57bad21efbb72e49a0edf0d13e9c249.tar.gz
chromium_src-73097564b57bad21efbb72e49a0edf0d13e9c249.tar.bz2
Reland 9034035: Make it possible to have 1 PpapiGlobals per thread.
Original CL: r117399, http://codereview.chromium.org/9034035/ Reverted in r117414, http://codereview.chromium.org/9139054/ due to a static initializer. This is the same as r117399 except using a LazyInstance to eliminate the static initializer. BUG= TEST= TBR=dmichael@chromium.org Review URL: http://codereview.chromium.org/9187055 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@117475 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--ppapi/proxy/host_dispatcher.cc6
-rw-r--r--ppapi/proxy/host_var_serialization_rules.cc38
-rw-r--r--ppapi/proxy/host_var_serialization_rules.h4
-rw-r--r--ppapi/proxy/plugin_globals.cc23
-rw-r--r--ppapi/proxy/plugin_globals.h14
-rw-r--r--ppapi/proxy/plugin_resource_tracker.cc10
-rw-r--r--ppapi/proxy/plugin_resource_tracker.h6
-rw-r--r--ppapi/proxy/plugin_var_serialization_rules.cc4
-rw-r--r--ppapi/proxy/plugin_var_tracker.cc17
-rw-r--r--ppapi/proxy/plugin_var_tracker.h8
-rw-r--r--ppapi/proxy/ppapi_proxy_test.cc16
-rw-r--r--ppapi/proxy/ppapi_proxy_test.h13
-rw-r--r--ppapi/proxy/ppb_var_unittest.cc28
-rw-r--r--ppapi/proxy/ppp_instance_private_proxy_unittest.cc117
-rw-r--r--ppapi/proxy/ppp_instance_proxy_unittest.cc27
-rw-r--r--ppapi/proxy/ppp_messaging_proxy_unittest.cc50
-rw-r--r--ppapi/proxy/serialized_var_unittest.cc5
-rw-r--r--ppapi/shared_impl/ppapi_globals.cc40
-rw-r--r--ppapi/shared_impl/ppapi_globals.h43
-rw-r--r--ppapi/shared_impl/proxy_lock.cc25
-rw-r--r--ppapi/shared_impl/proxy_lock.h10
-rw-r--r--ppapi/shared_impl/test_globals.cc11
-rw-r--r--ppapi/shared_impl/test_globals.h4
-rw-r--r--ppapi/shared_impl/var_tracker.cc17
-rw-r--r--ppapi/shared_impl/var_tracker.h8
-rw-r--r--webkit/plugins/ppapi/host_globals.cc18
-rw-r--r--webkit/plugins/ppapi/host_globals.h12
27 files changed, 351 insertions, 223 deletions
diff --git a/ppapi/proxy/host_dispatcher.cc b/ppapi/proxy/host_dispatcher.cc
index 1205189..efd1f56 100644
--- a/ppapi/proxy/host_dispatcher.cc
+++ b/ppapi/proxy/host_dispatcher.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -71,9 +71,7 @@ HostDispatcher::HostDispatcher(base::ProcessHandle remote_process_handle,
g_module_to_dispatcher = new ModuleToDispatcherMap;
(*g_module_to_dispatcher)[pp_module_] = this;
- const PPB_Var* var_interface =
- static_cast<const PPB_Var*>(local_get_interface(PPB_VAR_INTERFACE));
- SetSerializationRules(new HostVarSerializationRules(var_interface, module));
+ SetSerializationRules(new HostVarSerializationRules(module));
ppb_proxy_ = reinterpret_cast<const PPB_Proxy_Private*>(
local_get_interface(PPB_PROXY_PRIVATE_INTERFACE));
diff --git a/ppapi/proxy/host_var_serialization_rules.cc b/ppapi/proxy/host_var_serialization_rules.cc
index ae6b7f7..3f11090 100644
--- a/ppapi/proxy/host_var_serialization_rules.cc
+++ b/ppapi/proxy/host_var_serialization_rules.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,15 +6,19 @@
#include "base/logging.h"
#include "ppapi/c/ppb_var.h"
+#include "ppapi/shared_impl/ppapi_globals.h"
+#include "ppapi/shared_impl/var.h"
+#include "ppapi/shared_impl/var_tracker.h"
+
+using ppapi::PpapiGlobals;
+using ppapi::StringVar;
+using ppapi::VarTracker;
namespace ppapi {
namespace proxy {
-HostVarSerializationRules::HostVarSerializationRules(
- const PPB_Var* var_interface,
- PP_Module pp_module)
- : var_interface_(var_interface),
- pp_module_(pp_module) {
+HostVarSerializationRules::HostVarSerializationRules(PP_Module pp_module)
+ : pp_module_(pp_module) {
}
HostVarSerializationRules::~HostVarSerializationRules() {
@@ -31,18 +35,15 @@ PP_Var HostVarSerializationRules::BeginReceiveCallerOwned(
const PP_Var& var,
const std::string* str_val,
Dispatcher* /* dispatcher */) {
- if (var.type == PP_VARTYPE_STRING) {
- // Convert the string to the context of the current process.
- return var_interface_->VarFromUtf8(str_val->c_str(),
- static_cast<uint32_t>(str_val->size()));
- }
+ if (var.type == PP_VARTYPE_STRING)
+ return StringVar::StringToPPVar(*str_val);
return var;
}
void HostVarSerializationRules::EndReceiveCallerOwned(const PP_Var& var) {
if (var.type == PP_VARTYPE_STRING) {
// Destroy the string BeginReceiveCallerOwned created above.
- var_interface_->Release(var);
+ PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(var);
}
}
@@ -51,13 +52,12 @@ PP_Var HostVarSerializationRules::ReceivePassRef(const PP_Var& var,
Dispatcher* /* dispatcher */) {
if (var.type == PP_VARTYPE_STRING) {
// Convert the string to the context of the current process.
- return var_interface_->VarFromUtf8(str_val.c_str(),
- static_cast<uint32_t>(str_val.size()));
+ return StringVar::StringToPPVar(str_val);
}
// See PluginVarSerialization::BeginSendPassRef for an example.
if (var.type == PP_VARTYPE_OBJECT)
- var_interface_->AddRef(var);
+ PpapiGlobals::Get()->GetVarTracker()->AddRefVar(var);
return var;
}
@@ -83,13 +83,13 @@ void HostVarSerializationRules::VarToString(const PP_Var& var,
// This could be optimized to avoid an extra string copy by going to a lower
// level of the browser's implementation of strings where we already have
// a std::string.
- uint32_t len = 0;
- const char* data = var_interface_->VarToUtf8(var, &len);
- str->assign(data, len);
+ StringVar* string_var = StringVar::FromPPVar(var);
+ if (string_var)
+ *str = string_var->value();
}
void HostVarSerializationRules::ReleaseObjectRef(const PP_Var& var) {
- var_interface_->Release(var);
+ PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(var);
}
} // namespace proxy
diff --git a/ppapi/proxy/host_var_serialization_rules.h b/ppapi/proxy/host_var_serialization_rules.h
index 9c4db2e..bbbb3d7 100644
--- a/ppapi/proxy/host_var_serialization_rules.h
+++ b/ppapi/proxy/host_var_serialization_rules.h
@@ -18,8 +18,7 @@ namespace proxy {
// Implementation of the VarSerializationRules interface for the host side.
class HostVarSerializationRules : public VarSerializationRules {
public:
- HostVarSerializationRules(const PPB_Var* var_interface,
- PP_Module pp_module);
+ HostVarSerializationRules(PP_Module pp_module);
~HostVarSerializationRules();
// VarSerialization implementation.
@@ -40,7 +39,6 @@ class HostVarSerializationRules : public VarSerializationRules {
// string object.
void VarToString(const PP_Var& var, std::string* str);
- const PPB_Var* var_interface_;
PP_Module pp_module_;
DISALLOW_COPY_AND_ASSIGN(HostVarSerializationRules);
diff --git a/ppapi/proxy/plugin_globals.cc b/ppapi/proxy/plugin_globals.cc
index 664fbeb..360f221 100644
--- a/ppapi/proxy/plugin_globals.cc
+++ b/ppapi/proxy/plugin_globals.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -19,8 +19,15 @@ PluginGlobals::PluginGlobals()
plugin_globals_ = this;
}
+PluginGlobals::PluginGlobals(ForTest for_test)
+ : ppapi::PpapiGlobals(for_test),
+ plugin_proxy_delegate_(NULL),
+ callback_tracker_(new CallbackTracker) {
+ DCHECK(!plugin_globals_);
+}
+
PluginGlobals::~PluginGlobals() {
- DCHECK(plugin_globals_ == this);
+ DCHECK(plugin_globals_ == this || !plugin_globals_);
plugin_globals_ = NULL;
}
@@ -51,5 +58,17 @@ PP_Module PluginGlobals::GetModuleForInstance(PP_Instance instance) {
return 0;
}
+base::Lock* PluginGlobals::GetProxyLock() {
+#ifdef ENABLE_PEPPER_THREADING
+ return &proxy_lock_;
+#else
+ return NULL;
+#endif
+}
+
+bool PluginGlobals::IsPluginGlobals() const {
+ return true;
+}
+
} // namespace proxy
} // namespace ppapi
diff --git a/ppapi/proxy/plugin_globals.h b/ppapi/proxy/plugin_globals.h
index ffcf01e..0b47616 100644
--- a/ppapi/proxy/plugin_globals.h
+++ b/ppapi/proxy/plugin_globals.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,6 +6,7 @@
#define PPAPI_PROXY_PLUGIN_GLOBALS_H_
#include "base/compiler_specific.h"
+#include "base/synchronization/lock.h"
#include "ppapi/proxy/plugin_resource_tracker.h"
#include "ppapi/proxy/plugin_var_tracker.h"
#include "ppapi/proxy/ppapi_proxy_export.h"
@@ -20,12 +21,16 @@ class PluginProxyDelegate;
class PPAPI_PROXY_EXPORT PluginGlobals : public PpapiGlobals {
public:
PluginGlobals();
+ PluginGlobals(PpapiGlobals::ForTest);
virtual ~PluginGlobals();
// Getter for the global singleton. Generally, you should use
// PpapiGlobals::Get() when possible. Use this only when you need some
// plugin-specific functionality.
- inline static PluginGlobals* Get() { return plugin_globals_; }
+ inline static PluginGlobals* Get() {
+ DCHECK(PpapiGlobals::Get()->IsPluginGlobals());
+ return static_cast<PluginGlobals*>(PpapiGlobals::Get());
+ }
// PpapiGlobals implementation.
virtual ResourceTracker* GetResourceTracker() OVERRIDE;
@@ -35,6 +40,7 @@ class PPAPI_PROXY_EXPORT PluginGlobals : public PpapiGlobals {
virtual FunctionGroupBase* GetFunctionAPI(PP_Instance inst,
ApiID id) OVERRIDE;
virtual PP_Module GetModuleForInstance(PP_Instance instance) OVERRIDE;
+ virtual base::Lock* GetProxyLock() OVERRIDE;
// Getters for the plugin-specific versions.
PluginResourceTracker* plugin_resource_tracker() {
@@ -53,12 +59,16 @@ class PPAPI_PROXY_EXPORT PluginGlobals : public PpapiGlobals {
}
private:
+ // PpapiGlobals overrides.
+ virtual bool IsPluginGlobals() const OVERRIDE;
+
static PluginGlobals* plugin_globals_;
PluginProxyDelegate* plugin_proxy_delegate_;
PluginResourceTracker plugin_resource_tracker_;
PluginVarTracker plugin_var_tracker_;
scoped_refptr<CallbackTracker> callback_tracker_;
+ base::Lock proxy_lock_;
DISALLOW_COPY_AND_ASSIGN(PluginGlobals);
};
diff --git a/ppapi/proxy/plugin_resource_tracker.cc b/ppapi/proxy/plugin_resource_tracker.cc
index 3fee320..ac28de3 100644
--- a/ppapi/proxy/plugin_resource_tracker.cc
+++ b/ppapi/proxy/plugin_resource_tracker.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -18,17 +18,9 @@ namespace ppapi {
namespace proxy {
PluginResourceTracker::PluginResourceTracker() {
-#ifdef ENABLE_PEPPER_THREADING
- // Set the global proxy lock, since the plugin-side of the proxy needs to be
- // synchronized.
- ppapi::ProxyLock::Set(&proxy_lock_);
-#endif
}
PluginResourceTracker::~PluginResourceTracker() {
-#ifdef ENABLE_PEPPER_THREADING
- ppapi::ProxyLock::Reset();
-#endif
}
PP_Resource PluginResourceTracker::PluginResourceForHostResource(
diff --git a/ppapi/proxy/plugin_resource_tracker.h b/ppapi/proxy/plugin_resource_tracker.h
index 35c2385..6bed72f 100644
--- a/ppapi/proxy/plugin_resource_tracker.h
+++ b/ppapi/proxy/plugin_resource_tracker.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -9,7 +9,6 @@
#include <utility>
#include "base/compiler_specific.h"
-#include "base/synchronization/lock.h"
#include "ppapi/c/pp_completion_callback.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_stdint.h"
@@ -45,9 +44,6 @@ class PPAPI_PROXY_EXPORT PluginResourceTracker : public ResourceTracker {
typedef std::map<HostResource, PP_Resource> HostResourceMap;
HostResourceMap host_resource_map_;
- // The global lock for the plugin side of the proxy.
- base::Lock proxy_lock_;
-
DISALLOW_COPY_AND_ASSIGN(PluginResourceTracker);
};
diff --git a/ppapi/proxy/plugin_var_serialization_rules.cc b/ppapi/proxy/plugin_var_serialization_rules.cc
index a4eea5b..2e92dd5 100644
--- a/ppapi/proxy/plugin_var_serialization_rules.cc
+++ b/ppapi/proxy/plugin_var_serialization_rules.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -85,7 +85,7 @@ PP_Var PluginVarSerializationRules::ReceivePassRef(const PP_Var& var,
// plugin code started to return a value, which means it gets another ref
// on behalf of the caller. This needs to be transferred to the plugin and
// folded in to its set of refs it maintains (with one ref representing all
- // fo them in the browser).
+ // of them in the browser).
if (var.type == PP_VARTYPE_OBJECT) {
DCHECK(dispatcher->IsPlugin());
return var_tracker_->ReceiveObjectPassRef(
diff --git a/ppapi/proxy/plugin_var_tracker.cc b/ppapi/proxy/plugin_var_tracker.cc
index a7c83f3..525b1a3 100644
--- a/ppapi/proxy/plugin_var_tracker.cc
+++ b/ppapi/proxy/plugin_var_tracker.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -141,21 +141,6 @@ void PluginVarTracker::ReleaseHostObject(PluginDispatcher* dispatcher,
ReleaseVar(found->second);
}
-int PluginVarTracker::GetRefCountForObject(const PP_Var& plugin_object) {
- VarMap::iterator found = GetLiveVar(plugin_object);
- if (found == live_vars_.end())
- return -1;
- return found->second.ref_count;
-}
-
-int PluginVarTracker::GetTrackedWithNoReferenceCountForObject(
- const PP_Var& plugin_object) {
- VarMap::iterator found = GetLiveVar(plugin_object);
- if (found == live_vars_.end())
- return -1;
- return found->second.track_with_no_reference_count;
-}
-
ArrayBufferVar* PluginVarTracker::CreateArrayBuffer(uint32 size_in_bytes) {
return new PluginArrayBufferVar(size_in_bytes);
}
diff --git a/ppapi/proxy/plugin_var_tracker.h b/ppapi/proxy/plugin_var_tracker.h
index c2ede10..cafb3ab 100644
--- a/ppapi/proxy/plugin_var_tracker.h
+++ b/ppapi/proxy/plugin_var_tracker.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -56,12 +56,6 @@ class PPAPI_PROXY_EXPORT PluginVarTracker : public VarTracker {
void ReleaseHostObject(PluginDispatcher* dispatcher,
const PP_Var& host_object);
- // 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:
// VarTracker protected overrides.
virtual int32 AddVarInternal(Var* var, AddVarRefMode mode) OVERRIDE;
diff --git a/ppapi/proxy/ppapi_proxy_test.cc b/ppapi/proxy/ppapi_proxy_test.cc
index 8ab8c36..15dc967 100644
--- a/ppapi/proxy/ppapi_proxy_test.cc
+++ b/ppapi/proxy/ppapi_proxy_test.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -139,7 +139,8 @@ bool ProxyTestHarnessBase::SupportsInterface(const char* name) {
// PluginProxyTestHarness ------------------------------------------------------
-PluginProxyTestHarness::PluginProxyTestHarness() {
+PluginProxyTestHarness::PluginProxyTestHarness()
+ : plugin_globals_(PpapiGlobals::ForTest()) {
}
PluginProxyTestHarness::~PluginProxyTestHarness() {
@@ -151,6 +152,7 @@ Dispatcher* PluginProxyTestHarness::GetDispatcher() {
void PluginProxyTestHarness::SetUpHarness() {
// These must be first since the dispatcher set-up uses them.
+ PpapiGlobals::SetPpapiGlobalsOnThreadForTest(GetGlobals());
resource_tracker().DidCreateInstance(pp_instance());
plugin_dispatcher_.reset(new PluginDispatcher(
@@ -166,6 +168,7 @@ void PluginProxyTestHarness::SetUpHarnessWithChannel(
base::WaitableEvent* shutdown_event,
bool is_client) {
// These must be first since the dispatcher set-up uses them.
+ PpapiGlobals::SetPpapiGlobalsOnThreadForTest(GetGlobals());
resource_tracker().DidCreateInstance(pp_instance());
plugin_delegate_mock_.Init(ipc_message_loop, shutdown_event);
@@ -248,7 +251,8 @@ void PluginProxyTest::TearDown() {
// HostProxyTestHarness --------------------------------------------------------
-HostProxyTestHarness::HostProxyTestHarness() {
+HostProxyTestHarness::HostProxyTestHarness()
+ : host_globals_(PpapiGlobals::ForTest()) {
}
HostProxyTestHarness::~HostProxyTestHarness() {
@@ -259,6 +263,8 @@ Dispatcher* HostProxyTestHarness::GetDispatcher() {
}
void HostProxyTestHarness::SetUpHarness() {
+ // These must be first since the dispatcher set-up uses them.
+ PpapiGlobals::SetPpapiGlobalsOnThreadForTest(GetGlobals());
host_dispatcher_.reset(new HostDispatcher(
base::Process::Current().handle(),
pp_module(),
@@ -272,7 +278,10 @@ void HostProxyTestHarness::SetUpHarnessWithChannel(
base::MessageLoopProxy* ipc_message_loop,
base::WaitableEvent* shutdown_event,
bool is_client) {
+ // These must be first since the dispatcher set-up uses them.
+ PpapiGlobals::SetPpapiGlobalsOnThreadForTest(GetGlobals());
delegate_mock_.Init(ipc_message_loop, shutdown_event);
+
host_dispatcher_.reset(new HostDispatcher(
base::Process::Current().handle(),
pp_module(),
@@ -345,7 +354,6 @@ void TwoWayTest::SetUp() {
IPC::ChannelHandle handle;
handle.name = "TwoWayTestChannel";
-
base::WaitableEvent remote_harness_set_up(true, false);
plugin_thread_.message_loop_proxy()->PostTask(
FROM_HERE,
diff --git a/ppapi/proxy/ppapi_proxy_test.h b/ppapi/proxy/ppapi_proxy_test.h
index 2a612ed..5816188 100644
--- a/ppapi/proxy/ppapi_proxy_test.h
+++ b/ppapi/proxy/ppapi_proxy_test.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -17,6 +17,7 @@
#include "ppapi/proxy/plugin_proxy_delegate.h"
#include "ppapi/proxy/plugin_resource_tracker.h"
#include "ppapi/proxy/plugin_var_tracker.h"
+#include "ppapi/shared_impl/test_globals.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace ppapi {
@@ -33,6 +34,7 @@ class ProxyTestHarnessBase {
PP_Instance pp_instance() const { return pp_instance_; }
IPC::TestSink& sink() { return sink_; }
+ virtual PpapiGlobals* GetGlobals() = 0;
// Returns either the plugin or host dispatcher, depending on the test.
virtual Dispatcher* GetDispatcher() = 0;
@@ -88,6 +90,7 @@ class PluginProxyTestHarness : public ProxyTestHarnessBase {
}
// ProxyTestHarnessBase implementation.
+ virtual PpapiGlobals* GetGlobals() { return &plugin_globals_; }
virtual Dispatcher* GetDispatcher();
virtual void SetUpHarness();
virtual void SetUpHarnessWithChannel(const IPC::ChannelHandle& channel_handle,
@@ -157,8 +160,15 @@ class HostProxyTestHarness : public ProxyTestHarnessBase {
virtual ~HostProxyTestHarness();
HostDispatcher* host_dispatcher() { return host_dispatcher_.get(); }
+ ResourceTracker& resource_tracker() {
+ return *host_globals_.GetResourceTracker();
+ }
+ VarTracker& var_tracker() {
+ return *host_globals_.GetVarTracker();
+ }
// ProxyTestBase implementation.
+ virtual PpapiGlobals* GetGlobals() { return &host_globals_; }
virtual Dispatcher* GetDispatcher();
virtual void SetUpHarness();
virtual void SetUpHarnessWithChannel(const IPC::ChannelHandle& channel_handle,
@@ -191,6 +201,7 @@ class HostProxyTestHarness : public ProxyTestHarnessBase {
};
private:
+ ppapi::TestGlobals host_globals_;
scoped_ptr<HostDispatcher> host_dispatcher_;
DelegateMock delegate_mock_;
};
diff --git a/ppapi/proxy/ppb_var_unittest.cc b/ppapi/proxy/ppb_var_unittest.cc
index bf6147d..74ed453 100644
--- a/ppapi/proxy/ppb_var_unittest.cc
+++ b/ppapi/proxy/ppb_var_unittest.cc
@@ -10,6 +10,7 @@
#include "ppapi/c/pp_var.h"
#include "ppapi/c/ppb_var.h"
#include "ppapi/proxy/ppapi_proxy_test.h"
+#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/ppb_var_shared.h"
namespace {
@@ -96,12 +97,13 @@ class CreateVarThreadDelegate : public base::PlatformThread::Delegate {
// read the var back out to |strings_out[i]|.
CreateVarThreadDelegate(PP_Module pp_module, const std::string* strings_in,
PP_Var* vars_out, std::string* strings_out,
- size_t size)
+ size_t size, PpapiGlobals* globals)
: pp_module_(pp_module), strings_in_(strings_in), vars_out_(vars_out),
- strings_out_(strings_out), size_(size) {
+ strings_out_(strings_out), size_(size), globals_(globals) {
}
virtual ~CreateVarThreadDelegate() {}
virtual void ThreadMain() {
+ PpapiGlobals::SetPpapiGlobalsOnThreadForTest(globals_);
const PPB_Var* ppb_var = ppapi::PPB_Var_Shared::GetVarInterface1_1();
for (size_t i = 0; i < size_; ++i) {
vars_out_[i] = ppb_var->VarFromUtf8(strings_in_[i].c_str(),
@@ -115,16 +117,20 @@ class CreateVarThreadDelegate : public base::PlatformThread::Delegate {
PP_Var* vars_out_;
std::string* strings_out_;
size_t size_;
+ PpapiGlobals* globals_;
};
// A thread that will increment and decrement the reference count of every var
// multiple times.
class ChangeRefVarThreadDelegate : public base::PlatformThread::Delegate {
public:
- ChangeRefVarThreadDelegate(const std::vector<PP_Var>& vars) : vars_(vars) {
+ ChangeRefVarThreadDelegate(const std::vector<PP_Var>& vars,
+ PpapiGlobals* globals)
+ : vars_(vars), globals_(globals) {
}
virtual ~ChangeRefVarThreadDelegate() {}
virtual void ThreadMain() {
+ PpapiGlobals::SetPpapiGlobalsOnThreadForTest(globals_);
const PPB_Var* ppb_var = ppapi::PPB_Var_Shared::GetVarInterface1_1();
// Increment and decrement the reference count for each var kRefsToAdd
// times. Note that we always AddRef once before doing the matching Release,
@@ -144,15 +150,19 @@ class ChangeRefVarThreadDelegate : public base::PlatformThread::Delegate {
}
private:
std::vector<PP_Var> vars_;
+ PpapiGlobals* globals_;
};
// A thread that will decrement the reference count of every var once.
class RemoveRefVarThreadDelegate : public base::PlatformThread::Delegate {
public:
- RemoveRefVarThreadDelegate(const std::vector<PP_Var>& vars) : vars_(vars) {
+ RemoveRefVarThreadDelegate(const std::vector<PP_Var>& vars,
+ PpapiGlobals* globals)
+ : vars_(vars), globals_(globals) {
}
virtual ~RemoveRefVarThreadDelegate() {}
virtual void ThreadMain() {
+ PpapiGlobals::SetPpapiGlobalsOnThreadForTest(globals_);
const PPB_Var* ppb_var = ppapi::PPB_Var_Shared::GetVarInterface1_1();
for (size_t i = 0; i < kNumStrings; ++i) {
ppb_var->Release(vars_[i]);
@@ -160,6 +170,7 @@ class RemoveRefVarThreadDelegate : public base::PlatformThread::Delegate {
}
private:
std::vector<PP_Var> vars_;
+ PpapiGlobals* globals_;
};
} // namespace
@@ -186,7 +197,8 @@ TEST_F(PPB_VarTest, DISABLED_Threads) {
&vars_[slice_start],
&strings_out[slice_start],
std::min(strings_per_thread,
- kNumStrings - slice_start)));
+ kNumStrings - slice_start),
+ GetGlobals()));
}
// Now run then join all the threads.
for (size_t i = 0; i < kNumThreads; ++i)
@@ -201,7 +213,8 @@ TEST_F(PPB_VarTest, DISABLED_Threads) {
std::vector<base::PlatformThreadHandle> change_ref_var_threads(kNumThreads);
std::vector<ChangeRefVarThreadDelegate> change_ref_var_delegates;
for (size_t i = 0; i < kNumThreads; ++i)
- change_ref_var_delegates.push_back(ChangeRefVarThreadDelegate(vars_));
+ change_ref_var_delegates.push_back(
+ ChangeRefVarThreadDelegate(vars_, GetGlobals()));
for (size_t i = 0; i < kNumThreads; ++i) {
base::PlatformThread::Create(0, &change_ref_var_delegates[i],
&change_ref_var_threads[i]);
@@ -224,7 +237,8 @@ TEST_F(PPB_VarTest, DISABLED_Threads) {
std::vector<base::PlatformThreadHandle> remove_ref_var_threads(kNumThreads);
std::vector<RemoveRefVarThreadDelegate> remove_ref_var_delegates;
for (size_t i = 0; i < kNumThreads; ++i)
- remove_ref_var_delegates.push_back(RemoveRefVarThreadDelegate(vars_));
+ remove_ref_var_delegates.push_back(
+ RemoveRefVarThreadDelegate(vars_, GetGlobals()));
for (size_t i = 0; i < kNumThreads; ++i) {
base::PlatformThread::Create(0, &remove_ref_var_delegates[i],
&remove_ref_var_threads[i]);
diff --git a/ppapi/proxy/ppp_instance_private_proxy_unittest.cc b/ppapi/proxy/ppp_instance_private_proxy_unittest.cc
index ea57ec1..6b87f12 100644
--- a/ppapi/proxy/ppp_instance_private_proxy_unittest.cc
+++ b/ppapi/proxy/ppp_instance_private_proxy_unittest.cc
@@ -1,7 +1,11 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/bind.h"
+#include "base/message_loop.h"
+#include "base/test/test_timeouts.h"
+#include "base/time.h"
#include "ppapi/c/dev/ppb_var_deprecated.h"
#include "ppapi/c/dev/ppp_class_deprecated.h"
#include "ppapi/c/pp_var.h"
@@ -10,18 +14,31 @@
#include "ppapi/c/private/ppp_instance_private.h"
#include "ppapi/proxy/host_dispatcher.h"
#include "ppapi/proxy/ppapi_proxy_test.h"
+#include "ppapi/shared_impl/ppb_var_shared.h"
+#include "ppapi/shared_impl/var.h"
namespace ppapi {
+
+// A fake version of NPObjectVar for testing.
+class NPObjectVar : public ppapi::Var {
+ public:
+ NPObjectVar() {}
+ virtual ~NPObjectVar() {}
+
+ // Var overrides.
+ virtual NPObjectVar* AsNPObjectVar() OVERRIDE { return this; }
+ virtual PP_VarType GetType() const OVERRIDE { return PP_VARTYPE_OBJECT; }
+};
+
namespace proxy {
namespace {
const PP_Instance kInstance = 0xdeadbeef;
-PP_Var MakeObjectVar(int64_t object_id) {
- PP_Var ret;
- ret.type = PP_VARTYPE_OBJECT;
- ret.value.as_id = object_id;
- return ret;
+PP_Var GetPPVarNoAddRef(Var* var) {
+ PP_Var var_to_return = var->GetPPVar();
+ PpapiGlobals::Get()->GetVarTracker()->ReleaseVar(var_to_return);
+ return var_to_return;
}
PluginDispatcher* plugin_dispatcher = NULL;
@@ -40,7 +57,8 @@ PP_Var instance_obj;
PP_Var GetInstanceObject(PP_Instance /*instance*/) {
// The 1 ref we got from CreateObject will be passed to the host. We want to
// have a ref of our own.
- plugin_var_deprecated_if()->AddRef(instance_obj);
+ printf("GetInstanceObject called\n");
+ PpapiGlobals::Get()->GetVarTracker()->AddRefVar(instance_obj);
return instance_obj;
}
@@ -67,41 +85,19 @@ void DidDestroy(PP_Instance /*instance*/) {
PPP_Instance_1_0 ppp_instance_mock = { &DidCreate, &DidDestroy };
-} // namespace
-
// Mock PPB_Var_Deprecated, so that we can emulate creating an Object Var.
-std::map<int64_t, int> id_refcount_map;
-void AddRefVar(PP_Var var) {
- CHECK(var.type >= PP_VARTYPE_STRING); // Must be a ref-counted type.
- CHECK(id_refcount_map.find(var.value.as_id) != id_refcount_map.end());
- ++id_refcount_map[var.value.as_id];
-}
-
-void ReleaseVar(PP_Var var) {
- CHECK(var.type >= PP_VARTYPE_STRING); // Must be a ref-counted type.
- std::map<int64_t, int>::iterator iter = id_refcount_map.find(var.value.as_id);
- CHECK(iter != id_refcount_map.end());
- CHECK(iter->second > 0);
- if (--(iter->second) == 0)
- id_refcount_map.erase(iter);
-}
-
-PP_Var CreateObject(PP_Instance instance,
+PP_Var CreateObject(PP_Instance /*instance*/,
const PPP_Class_Deprecated* /*ppp_class*/,
void* /*ppp_class_data*/) {
- static int64_t last_id = 0;
- ++last_id;
- // Set the refcount to 0. It should really be 1, but that ref gets passed to
- // the plugin immediately (and we don't emulate all of that behavior here).
- id_refcount_map[last_id] = 0;
- return MakeObjectVar(last_id);
+ NPObjectVar* obj_var = new NPObjectVar;
+ return obj_var->GetPPVar();
}
const PPB_Var_Deprecated ppb_var_deprecated_mock = {
- &AddRefVar,
- &ReleaseVar,
- NULL, // VarFromUtf8
- NULL, // VarToUtf8
+ PPB_Var_Shared::GetVarInterface1_0()->AddRef,
+ PPB_Var_Shared::GetVarInterface1_0()->Release,
+ PPB_Var_Shared::GetVarInterface1_0()->VarFromUtf8,
+ PPB_Var_Shared::GetVarInterface1_0()->VarToUtf8,
NULL, // HasProperty
NULL, // HasMethod
NULL, // GetProperty
@@ -114,7 +110,7 @@ const PPB_Var_Deprecated ppb_var_deprecated_mock = {
&CreateObject
};
-const PPB_Var ppb_var_mock = { &AddRefVar, &ReleaseVar };
+} // namespace
class PPP_Instance_Private_ProxyTest : public TwoWayTest {
public:
@@ -126,8 +122,6 @@ class PPP_Instance_Private_ProxyTest : public TwoWayTest {
&ppp_instance_mock);
host().RegisterTestInterface(PPB_VAR_DEPRECATED_INTERFACE,
&ppb_var_deprecated_mock);
- host().RegisterTestInterface(PPB_VAR_INTERFACE,
- &ppb_var_mock);
}
};
@@ -146,44 +140,43 @@ TEST_F(PPP_Instance_Private_ProxyTest, PPPInstancePrivate) {
static_cast<const PPP_Instance_Private*>(
host().host_dispatcher()->GetProxiedInterface(
PPP_INSTANCE_PRIVATE_INTERFACE));
- const PPP_Instance_1_0* ppp_instance = static_cast<const PPP_Instance_1_0*>(
+ const PPP_Instance_1_1* ppp_instance = static_cast<const PPP_Instance_1_1*>(
host().host_dispatcher()->GetProxiedInterface(
- PPP_INSTANCE_INTERFACE_1_0));
+ PPP_INSTANCE_INTERFACE_1_1));
// Initialize an Instance, so that the plugin-side machinery will work
// properly.
EXPECT_EQ(PP_TRUE, ppp_instance->DidCreate(kInstance, 0, NULL, NULL));
- // Now instance_obj is valid and should have a ref-count of 1.
- PluginVarTracker& plugin_var_tracker =
- *PluginGlobals::Get()->plugin_var_tracker();
// Check the plugin-side reference count.
- EXPECT_EQ(1, plugin_var_tracker.GetRefCountForObject(instance_obj));
- // Check the host-side var and reference count.
- ASSERT_EQ(1u, id_refcount_map.size());
- EXPECT_EQ(plugin_var_tracker.GetHostObject(instance_obj).value.as_id,
- id_refcount_map.begin()->first);
- EXPECT_EQ(0, id_refcount_map.begin()->second);
+ EXPECT_EQ(1, plugin().var_tracker().GetRefCountForObject(instance_obj));
+ // Check the host-side var exists with the expected id and has 1 refcount (the
+ // refcount on behalf of the plugin).
+ int32 expected_host_id =
+ plugin().var_tracker().GetHostObject(instance_obj).value.as_id;
+ Var* host_var = host().var_tracker().GetVar(expected_host_id);
+ ASSERT_TRUE(host_var);
+ EXPECT_EQ(
+ 1,
+ host().var_tracker().GetRefCountForObject(GetPPVarNoAddRef(host_var)));
// Call from the browser side to get the instance object.
- PP_Var host_obj = ppp_instance_private->GetInstanceObject(kInstance);
- EXPECT_EQ(instance_obj.type, host_obj.type);
- EXPECT_EQ(host_obj.value.as_id,
- plugin_var_tracker.GetHostObject(instance_obj).value.as_id);
- EXPECT_EQ(1, plugin_var_tracker.GetRefCountForObject(instance_obj));
- ASSERT_EQ(1u, id_refcount_map.size());
- // The browser should be passed a reference.
- EXPECT_EQ(1, id_refcount_map.begin()->second);
+ PP_Var host_pp_var = ppp_instance_private->GetInstanceObject(kInstance);
+ EXPECT_EQ(instance_obj.type, host_pp_var.type);
+ EXPECT_EQ(host_pp_var.value.as_id, expected_host_id);
+ EXPECT_EQ(1, plugin().var_tracker().GetRefCountForObject(instance_obj));
+ // A reference is passed to the browser, which we consume here.
+ host().var_tracker().ReleaseVar(host_pp_var);
+ EXPECT_EQ(1, host().var_tracker().GetRefCountForObject(host_pp_var));
// The plugin is going away; generally, so will all references to its instance
// object.
- ReleaseVar(host_obj);
+ host().var_tracker().ReleaseVar(host_pp_var);
// Destroy the instance. DidDestroy above decrements the reference count for
// instance_obj, so it should also be destroyed.
ppp_instance->DidDestroy(kInstance);
- EXPECT_EQ(-1, plugin_var_tracker.GetRefCountForObject(instance_obj));
- // Check the host-side reference count.
- EXPECT_EQ(0u, id_refcount_map.size());
+ EXPECT_EQ(-1, plugin().var_tracker().GetRefCountForObject(instance_obj));
+ EXPECT_EQ(-1, host().var_tracker().GetRefCountForObject(host_pp_var));
}
} // namespace proxy
diff --git a/ppapi/proxy/ppp_instance_proxy_unittest.cc b/ppapi/proxy/ppp_instance_proxy_unittest.cc
index c97ef21..6e53023 100644
--- a/ppapi/proxy/ppp_instance_proxy_unittest.cc
+++ b/ppapi/proxy/ppp_instance_proxy_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -12,6 +12,8 @@
#include "ppapi/c/private/ppb_flash_fullscreen.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/ppapi_proxy_test.h"
+#include "ppapi/shared_impl/ppb_view_shared.h"
+#include "ppapi/shared_impl/scoped_pp_resource.h"
namespace ppapi {
namespace proxy {
@@ -114,10 +116,11 @@ TEST_F(PPP_Instance_ProxyTest, PPPInstance1_0) {
host().RegisterTestInterface(PPB_FULLSCREEN_INTERFACE,
&ppb_fullscreen);
- // Grab the host-side proxy for the 1.0 interface.
- const PPP_Instance_1_0* ppp_instance = static_cast<const PPP_Instance_1_0*>(
+ // Grab the host-side proxy for the interface. The browser only speaks 1.1,
+ // while the proxy ensures support for the 1.0 version on the plugin side.
+ const PPP_Instance_1_1* ppp_instance = static_cast<const PPP_Instance_1_1*>(
host().host_dispatcher()->GetProxiedInterface(
- PPP_INSTANCE_INTERFACE_1_0));
+ PPP_INSTANCE_INTERFACE_1_1));
// Call each function in turn, make sure we get the expected values and
// returns.
@@ -140,6 +143,8 @@ TEST_F(PPP_Instance_ProxyTest, PPPInstance1_0) {
uint32_t expected_argc = expected_argn.size();
bool_to_return = PP_TRUE;
ResetReceived();
+ // Tell the host resource tracker about the instance.
+ host().resource_tracker().DidCreateInstance(expected_instance);
EXPECT_EQ(bool_to_return, ppp_instance->DidCreate(expected_instance,
expected_argc,
&argn_to_pass[0],
@@ -151,9 +156,17 @@ TEST_F(PPP_Instance_ProxyTest, PPPInstance1_0) {
PP_Rect expected_position = { {1, 2}, {3, 4} };
PP_Rect expected_clip = { {5, 6}, {7, 8} };
+ ViewData data;
+ data.rect = expected_position;
+ data.is_fullscreen = false;
+ data.is_page_visible = true;
+ data.clip_rect = expected_clip;
ResetReceived();
- ppp_instance->DidChangeView(expected_instance, &expected_position,
- &expected_clip);
+ ScopedPPResource view_resource(
+ ScopedPPResource::PassRef(),
+ (new PPB_View_Shared(PPB_View_Shared::InitAsImpl(),
+ expected_instance, data))->GetReference());
+ ppp_instance->DidChangeView(expected_instance, view_resource);
did_change_view_called.Wait();
EXPECT_EQ(received_instance, expected_instance);
EXPECT_EQ(received_position.point.x, expected_position.point.x);
@@ -176,6 +189,8 @@ TEST_F(PPP_Instance_ProxyTest, PPPInstance1_0) {
// HandleResourceLoad. It also requires
// PPB_Core.AddRefResource and for PPB_URLLoader to be
// registered.
+
+ host().resource_tracker().DidDeleteInstance(expected_instance);
}
} // namespace proxy
diff --git a/ppapi/proxy/ppp_messaging_proxy_unittest.cc b/ppapi/proxy/ppp_messaging_proxy_unittest.cc
index ed12e57..8e46a4a 100644
--- a/ppapi/proxy/ppp_messaging_proxy_unittest.cc
+++ b/ppapi/proxy/ppp_messaging_proxy_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -41,38 +41,15 @@ PPP_Messaging ppp_messaging_mock = {
&HandleMessage
};
-// Define a fake PPB_Var for the host side so that we can send a string var.
-void AddRef(PP_Var /*var*/) {
-}
-void Release(PP_Var /*var*/) {
-}
-PP_Var VarFromUtf8(const char* /*data*/, uint32_t len) {
- return PP_MakeUndefined();
-}
-// No matter what id we're given, always provide kTestString and its length.
-const std::string kTestString = "Hello world!";
-const char* VarToUtf8(PP_Var /*var*/, uint32_t* len) {
- *len = kTestString.size();
- return kTestString.c_str();
-}
-
-PPB_Var ppb_var_mock = {
- &AddRef,
- &Release,
- &VarFromUtf8,
- &VarToUtf8
-};
-
} // namespace
class PPP_Messaging_ProxyTest : public TwoWayTest {
public:
- PPP_Messaging_ProxyTest()
- : TwoWayTest(TwoWayTest::TEST_PPP_INTERFACE) {
- plugin().RegisterTestInterface(PPP_MESSAGING_INTERFACE,
- &ppp_messaging_mock);
- host().RegisterTestInterface(PPB_VAR_INTERFACE, &ppb_var_mock);
- }
+ PPP_Messaging_ProxyTest()
+ : TwoWayTest(TwoWayTest::TEST_PPP_INTERFACE) {
+ plugin().RegisterTestInterface(PPP_MESSAGING_INTERFACE,
+ &ppp_messaging_mock);
+ }
};
TEST_F(PPP_Messaging_ProxyTest, SendMessages) {
@@ -120,17 +97,22 @@ TEST_F(PPP_Messaging_ProxyTest, SendMessages) {
EXPECT_EQ(expected_var.type, received_var.type);
EXPECT_EQ(expected_var.value.as_double, received_var.value.as_double);
- expected_var.type = PP_VARTYPE_STRING;
- expected_var.value.as_id = 1979;
+ const std::string kTestString("Hello world!");
+ expected_var = StringVar::StringToPPVar(kTestString);
ResetReceived();
ppp_messaging->HandleMessage(expected_instance, expected_var);
+ // Now release the var, and the string should go away (because the ref
+ // count should be one).
+ host().var_tracker().ReleaseVar(expected_var);
+ EXPECT_FALSE(StringVar::FromPPVar(expected_var));
+
handle_message_called.Wait();
EXPECT_EQ(expected_instance, received_instance);
EXPECT_EQ(expected_var.type, received_var.type);
-
- StringVar* received_string = StringVar::FromPPVar(received_var);
+ Var* received_string = plugin().var_tracker().GetVar(received_var);
ASSERT_TRUE(received_string);
- EXPECT_EQ(kTestString, received_string->value());
+ ASSERT_TRUE(received_string->AsStringVar());
+ EXPECT_EQ(kTestString, received_string->AsStringVar()->value());
// Now release the var, and the string should go away (because the ref
// count should be one).
plugin().var_tracker().ReleaseVar(received_var);
diff --git a/ppapi/proxy/serialized_var_unittest.cc b/ppapi/proxy/serialized_var_unittest.cc
index 150f5e7..494a68d 100644
--- a/ppapi/proxy/serialized_var_unittest.cc
+++ b/ppapi/proxy/serialized_var_unittest.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -115,7 +115,8 @@ TEST_F(SerializedVarTest, PluginSerializedStringVarInOutParam) {
EXPECT_EQ(0u, sink().message_count());
}
-// Tests receiving an argument and passing it back out as an output parameter.
+// Tests receiving an argument and passing it back to the browser as an output
+// parameter.
TEST_F(SerializedVarTest, PluginSerializedVarOutParam) {
PP_Var host_object = MakeObjectVar(0x31337);
diff --git a/ppapi/shared_impl/ppapi_globals.cc b/ppapi/shared_impl/ppapi_globals.cc
index 9b5e9a8..0fab3dc 100644
--- a/ppapi/shared_impl/ppapi_globals.cc
+++ b/ppapi/shared_impl/ppapi_globals.cc
@@ -1,13 +1,24 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ppapi/shared_impl/ppapi_globals.h"
+#include "base/lazy_instance.h" // For testing purposes only.
#include "base/logging.h"
+#include "base/threading/thread_local.h" // For testing purposes only.
namespace ppapi {
+namespace {
+// Thread-local globals for testing. See SetPpapiGlobalsOnThreadForTest for more
+// information.
+base::LazyInstance<
+ base::ThreadLocalPointer<PpapiGlobals>,
+ base::LeakyLazyInstanceTraits<base::ThreadLocalPointer<PpapiGlobals> > >
+ tls_ppapi_globals_for_test = LAZY_INSTANCE_INITIALIZER;
+} // namespace
+
PpapiGlobals* PpapiGlobals::ppapi_globals_ = NULL;
PpapiGlobals::PpapiGlobals() {
@@ -15,9 +26,34 @@ PpapiGlobals::PpapiGlobals() {
ppapi_globals_ = this;
}
+PpapiGlobals::PpapiGlobals(ForTest) {
+ DCHECK(!ppapi_globals_);
+}
+
PpapiGlobals::~PpapiGlobals() {
- DCHECK(ppapi_globals_ == this);
+ DCHECK(ppapi_globals_ == this || !ppapi_globals_);
ppapi_globals_ = NULL;
}
+// static
+void PpapiGlobals::SetPpapiGlobalsOnThreadForTest(PpapiGlobals* ptr) {
+ // If we're using a per-thread PpapiGlobals, we should not have a global one.
+ // If we allowed it, it would always over-ride the "test" versions.
+ DCHECK(!ppapi_globals_);
+ tls_ppapi_globals_for_test.Pointer()->Set(ptr);
+}
+
+bool PpapiGlobals::IsHostGlobals() const {
+ return false;
+}
+
+bool PpapiGlobals::IsPluginGlobals() const {
+ return false;
+}
+
+// static
+PpapiGlobals* PpapiGlobals::GetThreadLocalPointer() {
+ return tls_ppapi_globals_for_test.Pointer()->Get();
+}
+
} // namespace ppapi
diff --git a/ppapi/shared_impl/ppapi_globals.h b/ppapi/shared_impl/ppapi_globals.h
index b3d7d55..737c3a2 100644
--- a/ppapi/shared_impl/ppapi_globals.h
+++ b/ppapi/shared_impl/ppapi_globals.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -6,11 +6,16 @@
#define PPAPI_SHARED_IMPL_PPAPI_GLOBALS_H_
#include "base/basictypes.h"
+#include "base/threading/thread_local.h" // For testing purposes only.
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_module.h"
#include "ppapi/shared_impl/api_id.h"
#include "ppapi/shared_impl/ppapi_shared_export.h"
+namespace base {
+class Lock;
+}
+
namespace ppapi {
class CallbackTracker;
@@ -22,16 +27,42 @@ class VarTracker;
class PPAPI_SHARED_EXPORT PpapiGlobals {
public:
PpapiGlobals();
+
+ // This constructor is to be used only for making a PpapiGlobal for testing
+ // purposes. This avoids setting the global static ppapi_globals_. For unit
+ // tests that use this feature, the "test" PpapiGlobals should be constructed
+ // using this method. See SetPpapiGlobalsOnThreadForTest for more information.
+ struct ForTest {};
+ PpapiGlobals(ForTest);
+
virtual ~PpapiGlobals();
// Getter for the global singleton.
- inline static PpapiGlobals* Get() { return ppapi_globals_; }
+ inline static PpapiGlobals* Get() {
+ if (ppapi_globals_)
+ return ppapi_globals_;
+ // In unit tests, the following might be valid (see
+ // SetPpapiGlobalsOnThreadForTest). Normally, this will just return NULL.
+ return GetThreadLocalPointer();
+ }
+
+ // This allows us to set a given PpapiGlobals object as the PpapiGlobals for
+ // a given thread. After setting the PpapiGlobals for a thread, Get() will
+ // return that PpapiGlobals when Get() is called on that thread. Other threads
+ // are unaffected. This allows us to have tests which use >1 PpapiGlobals in
+ // the same process, e.g. for having 1 thread emulate the "host" and 1 thread
+ // emulate the "plugin".
+ //
+ // PpapiGlobals object must have been constructed using the "ForTest"
+ // parameter.
+ static void SetPpapiGlobalsOnThreadForTest(PpapiGlobals* ptr);
// Retrieves the corresponding tracker.
virtual ResourceTracker* GetResourceTracker() = 0;
virtual VarTracker* GetVarTracker() = 0;
virtual CallbackTracker* GetCallbackTrackerForInstance(
PP_Instance instance) = 0;
+ virtual base::Lock* GetProxyLock() = 0;
// Returns the function object corresponding to the given ID, or NULL if
// there isn't one.
@@ -41,7 +72,15 @@ class PPAPI_SHARED_EXPORT PpapiGlobals {
// failure.
virtual PP_Module GetModuleForInstance(PP_Instance instance) = 0;
+ virtual bool IsHostGlobals() const;
+ virtual bool IsPluginGlobals() const;
+
private:
+ // Return the thread-local pointer which is used only for unit testing. It
+ // should always be NULL when running in production. It allows separate
+ // threads to have distinct "globals".
+ static PpapiGlobals* GetThreadLocalPointer();
+
static PpapiGlobals* ppapi_globals_;
DISALLOW_COPY_AND_ASSIGN(PpapiGlobals);
diff --git a/ppapi/shared_impl/proxy_lock.cc b/ppapi/shared_impl/proxy_lock.cc
index 3d84930..226c51f 100644
--- a/ppapi/shared_impl/proxy_lock.cc
+++ b/ppapi/shared_impl/proxy_lock.cc
@@ -1,35 +1,26 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "ppapi/shared_impl/proxy_lock.h"
#include "base/synchronization/lock.h"
+#include "ppapi/shared_impl/ppapi_globals.h"
namespace ppapi {
-base::Lock* ProxyLock::lock_ = NULL;
-
// static
void ProxyLock::Acquire() {
- if (lock_)
- lock_->Acquire();
+ base::Lock* lock(PpapiGlobals::Get()->GetProxyLock());
+ if (lock)
+ lock->Acquire();
}
// static
void ProxyLock::Release() {
- if (lock_)
- lock_->Release();
-}
-
-// static
-void ProxyLock::Set(base::Lock* lock) {
- lock_ = lock;
-}
-
-// static
-void ProxyLock::Reset() {
- Set(NULL);
+ base::Lock* lock(PpapiGlobals::Get()->GetProxyLock());
+ if (lock)
+ lock->Release();
}
} // namespace ppapi
diff --git a/ppapi/shared_impl/proxy_lock.h b/ppapi/shared_impl/proxy_lock.h
index cc90501..c5571f3 100644
--- a/ppapi/shared_impl/proxy_lock.h
+++ b/ppapi/shared_impl/proxy_lock.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -34,14 +34,6 @@ class PPAPI_SHARED_EXPORT ProxyLock {
// Relinquish the proxy lock. If the lock has not been set, this does nothing.
static void Release();
- // Set the lock that ProxyLock will use. The caller is responsible for
- // ensuring that the lock stays valid so long as the ProxyLock may be in use.
- static void Set(base::Lock* lock);
- // Set the lock to NULL.
- static void Reset();
- private:
- static base::Lock* lock_;
-
DISALLOW_IMPLICIT_CONSTRUCTORS(ProxyLock);
};
diff --git a/ppapi/shared_impl/test_globals.cc b/ppapi/shared_impl/test_globals.cc
index e870e5c..f661998 100644
--- a/ppapi/shared_impl/test_globals.cc
+++ b/ppapi/shared_impl/test_globals.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,6 +11,11 @@ TestGlobals::TestGlobals()
callback_tracker_(new CallbackTracker) {
}
+TestGlobals::TestGlobals(PpapiGlobals::ForTest for_test)
+ : ppapi::PpapiGlobals(for_test),
+ callback_tracker_(new CallbackTracker) {
+}
+
TestGlobals::~TestGlobals() {
}
@@ -35,4 +40,8 @@ PP_Module TestGlobals::GetModuleForInstance(PP_Instance instance) {
return 0;
}
+base::Lock* TestGlobals::GetProxyLock() {
+ return NULL;
+}
+
} // namespace ppapi
diff --git a/ppapi/shared_impl/test_globals.h b/ppapi/shared_impl/test_globals.h
index 9c58fd3..9af6664 100644
--- a/ppapi/shared_impl/test_globals.h
+++ b/ppapi/shared_impl/test_globals.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -27,6 +27,7 @@ class TestVarTracker : public VarTracker {
class TestGlobals : public PpapiGlobals {
public:
TestGlobals();
+ TestGlobals(PpapiGlobals::ForTest);
virtual ~TestGlobals();
// PpapiGlobals implementation.
@@ -37,6 +38,7 @@ class TestGlobals : public PpapiGlobals {
virtual FunctionGroupBase* GetFunctionAPI(PP_Instance inst,
ApiID id) OVERRIDE;
virtual PP_Module GetModuleForInstance(PP_Instance instance) OVERRIDE;
+ virtual base::Lock* GetProxyLock() OVERRIDE;
private:
ResourceTracker resource_tracker_;
diff --git a/ppapi/shared_impl/var_tracker.cc b/ppapi/shared_impl/var_tracker.cc
index 58c715c..0b70349 100644
--- a/ppapi/shared_impl/var_tracker.cc
+++ b/ppapi/shared_impl/var_tracker.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -129,6 +129,21 @@ VarTracker::VarMap::iterator VarTracker::GetLiveVar(int32 id) {
return live_vars_.find(id);
}
+int VarTracker::GetRefCountForObject(const PP_Var& plugin_object) {
+ VarMap::iterator found = GetLiveVar(plugin_object);
+ if (found == live_vars_.end())
+ return -1;
+ return found->second.ref_count;
+}
+
+int VarTracker::GetTrackedWithNoReferenceCountForObject(
+ const PP_Var& plugin_object) {
+ VarMap::iterator found = GetLiveVar(plugin_object);
+ if (found == live_vars_.end())
+ return -1;
+ return found->second.track_with_no_reference_count;
+}
+
VarTracker::VarMap::iterator VarTracker::GetLiveVar(const PP_Var& var) {
return live_vars_.find(static_cast<int32>(var.value.as_id));
}
diff --git a/ppapi/shared_impl/var_tracker.h b/ppapi/shared_impl/var_tracker.h
index 4dc8a2d..52e38bd 100644
--- a/ppapi/shared_impl/var_tracker.h
+++ b/ppapi/shared_impl/var_tracker.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -68,6 +68,12 @@ class PPAPI_SHARED_EXPORT VarTracker {
// and their reference counts are unaffected.
std::vector<PP_Var> GetLiveVars();
+ // 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& object);
+ int GetTrackedWithNoReferenceCountForObject(const PP_Var& object);
+
protected:
struct VarInfo {
VarInfo();
diff --git a/webkit/plugins/ppapi/host_globals.cc b/webkit/plugins/ppapi/host_globals.cc
index ab51983..7705dcc 100644
--- a/webkit/plugins/ppapi/host_globals.cc
+++ b/webkit/plugins/ppapi/host_globals.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -45,8 +45,13 @@ HostGlobals::HostGlobals() : ::ppapi::PpapiGlobals() {
host_globals_ = this;
}
+HostGlobals::HostGlobals(::ppapi::PpapiGlobals::ForTest for_test)
+ : ::ppapi::PpapiGlobals(for_test) {
+ DCHECK(!host_globals_);
+}
+
HostGlobals::~HostGlobals() {
- DCHECK(host_globals_ == this);
+ DCHECK(host_globals_ == this || !host_globals_);
host_globals_ = NULL;
}
@@ -116,6 +121,11 @@ PP_Module HostGlobals::GetModuleForInstance(PP_Instance instance) {
return inst->module()->pp_module();
}
+base::Lock* HostGlobals::GetProxyLock() {
+ // We do not lock on the host side.
+ return NULL;
+}
+
PP_Module HostGlobals::AddModule(PluginModule* module) {
#ifndef NDEBUG
// Make sure we're not adding one more than once.
@@ -197,5 +207,9 @@ PluginInstance* HostGlobals::GetInstance(PP_Instance instance) {
return found->second->instance;
}
+bool HostGlobals::IsHostGlobals() const {
+ return true;
+}
+
} // namespace ppapi
} // namespace webkit
diff --git a/webkit/plugins/ppapi/host_globals.h b/webkit/plugins/ppapi/host_globals.h
index db840aa..d0926bc 100644
--- a/webkit/plugins/ppapi/host_globals.h
+++ b/webkit/plugins/ppapi/host_globals.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -22,12 +22,16 @@ class PluginModule;
class HostGlobals : public ::ppapi::PpapiGlobals {
public:
HostGlobals();
+ HostGlobals(::ppapi::PpapiGlobals::ForTest);
virtual ~HostGlobals();
// Getter for the global singleton. Generally, you should use
// PpapiGlobals::Get() when possible. Use this only when you need some
// host-specific functionality.
- inline static HostGlobals* Get() { return host_globals_; }
+ inline static HostGlobals* Get() {
+ DCHECK(PpapiGlobals::Get()->IsHostGlobals());
+ return static_cast<HostGlobals*>(PpapiGlobals::Get());
+ }
// PpapiGlobals implementation.
virtual ::ppapi::ResourceTracker* GetResourceTracker() OVERRIDE;
@@ -38,6 +42,7 @@ class HostGlobals : public ::ppapi::PpapiGlobals {
PP_Instance inst,
::ppapi::ApiID id) OVERRIDE;
virtual PP_Module GetModuleForInstance(PP_Instance instance) OVERRIDE;
+ virtual base::Lock* GetProxyLock() OVERRIDE;
HostVarTracker* host_var_tracker() {
return &host_var_tracker_;
@@ -75,6 +80,9 @@ class HostGlobals : public ::ppapi::PpapiGlobals {
WEBKIT_PLUGINS_EXPORT PluginInstance* GetInstance(PP_Instance instance);
private:
+ // PpapiGlobals overrides.
+ virtual bool IsHostGlobals() const OVERRIDE;
+
// Per-instance data we track.
struct InstanceData;