Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1066)

Unified Diff: ppapi/shared_impl/thread_aware_callback_unittest.cc

Issue 11859015: Pepper: Introduce ThreadAwareCallback. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ppapi/shared_impl/thread_aware_callback.cc ('k') | webkit/plugins/ppapi/host_globals.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ppapi/shared_impl/thread_aware_callback_unittest.cc
diff --git a/ppapi/shared_impl/thread_aware_callback_unittest.cc b/ppapi/shared_impl/thread_aware_callback_unittest.cc
new file mode 100644
index 0000000000000000000000000000000000000000..f86048a76900bb49f317052ed28214db41cc923c
--- /dev/null
+++ b/ppapi/shared_impl/thread_aware_callback_unittest.cc
@@ -0,0 +1,218 @@
+// 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/thread_aware_callback.h"
+
+#include "base/bind_helpers.h"
+#include "base/compiler_specific.h"
+#include "base/logging.h"
+#include "base/memory/scoped_ptr.h"
+#include "ppapi/c/pp_errors.h"
+#include "ppapi/proxy/ppapi_proxy_test.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace ppapi {
+
+namespace {
+
+class TestParameter {
+ public:
+ TestParameter() : value_(0) {
+ }
+
+ int value_;
+};
+
+int called_num = 0;
+
+void TestCallback_0() {
+ ++called_num;
+}
+
+void TestCallback_1(int p1) {
+ ++called_num;
+}
+
+void TestCallback_2(int p1, const double* p2) {
+ ++called_num;
+}
+
+void TestCallback_3(int p1, const double* p2, bool* p3) {
+ ++called_num;
+}
+
+void TestCallback_4(int p1, const double* p2, bool* p3, TestParameter p4) {
+ ++called_num;
+}
+
+void TestCallback_5(int p1,
+ const double* p2,
+ bool* p3,
+ TestParameter p4,
+ const TestParameter& p5) {
+ ++called_num;
+}
+
+typedef proxy::PluginProxyTest ThreadAwareCallbackTest;
+
+// Test that a callback created on the main thread will run on the main thread,
+// even when requested from a different thread.
+class ThreadAwareCallbackMultiThreadTest
+ : public proxy::PluginProxyMultiThreadTest {
+ public:
+ ThreadAwareCallbackMultiThreadTest() : main_thread_callback_called_(false) {
+ }
+ virtual ~ThreadAwareCallbackMultiThreadTest() {
+ CHECK(main_thread_callback_called_);
+ }
+
+ // proxy::PluginProxyMultiThreadTest implementation.
+ virtual void SetUpTestOnMainThread() OVERRIDE {
+ ProxyAutoLock auto_lock;
+
+ main_thread_callback_.reset(
+ ThreadAwareCallback<CallbackFunc>::Create(&MainThreadCallbackBody));
+ }
+
+ virtual void SetUpTestOnSecondaryThread() OVERRIDE {
+ {
+ ProxyAutoLock auto_lock;
+ main_thread_callback_->RunOnTargetThread(this);
+ }
+
+ PostQuitForSecondaryThread();
+ PostQuitForMainThread();
+ }
+
+ private:
+ typedef void (*CallbackFunc)(ThreadAwareCallbackMultiThreadTest*);
+
+ static void MainThreadCallbackBody(ThreadAwareCallbackMultiThreadTest* thiz) {
+ thiz->CheckOnThread(MAIN_THREAD);
+ thiz->main_thread_callback_called_ = true;
+
+ {
+ ProxyAutoLock auto_lock;
+ // We have to destroy it prior to the PluginGlobals instance held by the
+ // base class. Otherwise it has a ref to Pepper message loop for the main
+ // thread and the PluginGlobals destructor will complain.
+ thiz->main_thread_callback_.reset(NULL);
+ }
+ }
+
+ scoped_ptr<ThreadAwareCallback<CallbackFunc> > main_thread_callback_;
+ bool main_thread_callback_called_;
+};
+
+// Test that when a ThreadAwareCallback instance is destroyed, pending tasks to
+// run the callback will be ignored.
+class ThreadAwareCallbackAbortTest : public proxy::PluginProxyMultiThreadTest {
+ public:
+ ThreadAwareCallbackAbortTest() {
+ }
+ virtual ~ThreadAwareCallbackAbortTest() {
+ }
+
+ // proxy::PluginProxyMultiThreadTest implementation.
+ virtual void SetUpTestOnMainThread() OVERRIDE {
+ ProxyAutoLock auto_lock;
+
+ main_thread_callback_.reset(
+ ThreadAwareCallback<CallbackFunc>::Create(&MainThreadCallbackBody));
+ }
+
+ virtual void SetUpTestOnSecondaryThread() OVERRIDE {
+ {
+ ProxyAutoLock auto_lock;
+ main_thread_message_loop_proxy_->PostTask(
+ FROM_HERE,
+ base::Bind(&ThreadAwareCallbackAbortTest::DeleteCallback,
+ base::Unretained(this)));
+ // |main_thread_callback_| is still valid, even if DeleteCallback() can be
+ // called before this following statement. That is because |auto_lock| is
+ // still held by this method, which prevents DeleteCallback() from
+ // deleting the callback.
+ main_thread_callback_->RunOnTargetThread(this);
+ }
+
+ PostQuitForSecondaryThread();
+ PostQuitForMainThread();
+ }
+
+ private:
+ typedef void (*CallbackFunc)(ThreadAwareCallbackAbortTest*);
+
+ static void MainThreadCallbackBody(ThreadAwareCallbackAbortTest* thiz) {
+ // The callback should not be called.
+ ASSERT_TRUE(false);
+ }
+
+ void DeleteCallback() {
+ ProxyAutoLock auto_lock;
+ main_thread_callback_.reset(NULL);
+ }
+
+ scoped_ptr<ThreadAwareCallback<CallbackFunc> > main_thread_callback_;
+};
+
+} // namespace
+
+TEST_F(ThreadAwareCallbackTest, Basics) {
+ // ThreadAwareCallback should only be used when the proxy lock has been
+ // acquired.
+ ProxyAutoLock auto_lock;
+
+ double double_arg = 0.0;
+ bool bool_arg = false;
+ TestParameter object_arg;
+
+ // Exercise all the template code.
+ called_num = 0;
+ typedef void (*FuncType_0)();
+ scoped_ptr<ThreadAwareCallback<FuncType_0> > callback_0(
+ ThreadAwareCallback<FuncType_0>::Create(TestCallback_0));
+ callback_0->RunOnTargetThread();
+
+ typedef void (*FuncType_1)(int);
+ scoped_ptr<ThreadAwareCallback<FuncType_1> > callback_1(
+ ThreadAwareCallback<FuncType_1>::Create(TestCallback_1));
+ callback_1->RunOnTargetThread(1);
+
+ typedef void (*FuncType_2)(int, const double*);
+ scoped_ptr<ThreadAwareCallback<FuncType_2> > callback_2(
+ ThreadAwareCallback<FuncType_2>::Create(TestCallback_2));
+ callback_2->RunOnTargetThread(1, &double_arg);
+
+ typedef void (*FuncType_3)(int, const double*, bool*);
+ scoped_ptr<ThreadAwareCallback<FuncType_3> > callback_3(
+ ThreadAwareCallback<FuncType_3>::Create(TestCallback_3));
+ callback_3->RunOnTargetThread(1, &double_arg, &bool_arg);
+
+ typedef void (*FuncType_4)(int, const double*, bool*, TestParameter);
+ scoped_ptr<ThreadAwareCallback<FuncType_4> > callback_4(
+ ThreadAwareCallback<FuncType_4>::Create(TestCallback_4));
+ callback_4->RunOnTargetThread(1, &double_arg, &bool_arg, object_arg);
+
+ typedef void (*FuncType_5)(int,
+ const double*,
+ bool*,
+ TestParameter,
+ const TestParameter&);
+ scoped_ptr<ThreadAwareCallback<FuncType_5> > callback_5(
+ ThreadAwareCallback<FuncType_5>::Create(TestCallback_5));
+ callback_5->RunOnTargetThread(1, &double_arg, &bool_arg, object_arg,
+ object_arg);
+
+ EXPECT_EQ(6, called_num);
+}
+
+TEST_F(ThreadAwareCallbackMultiThreadTest, RunOnTargetThread) {
+ RunTest();
+}
+
+TEST_F(ThreadAwareCallbackAbortTest, NotRunIfAborted) {
+ RunTest();
+}
+
+} // namespace ppapi
« no previous file with comments | « ppapi/shared_impl/thread_aware_callback.cc ('k') | webkit/plugins/ppapi/host_globals.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698