Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / ppapi / shared_impl / thread_aware_callback_unittest.cc
blob5173753781947da4dbf646a7ed908c95c9b5a4a9
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ppapi/shared_impl/thread_aware_callback.h"
7 #include "base/bind_helpers.h"
8 #include "base/compiler_specific.h"
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "ppapi/c/pp_errors.h"
12 #include "ppapi/proxy/ppapi_proxy_test.h"
13 #include "testing/gtest/include/gtest/gtest.h"
15 namespace ppapi {
17 namespace {
19 class TestParameter {
20 public:
21 TestParameter() : value_(0) {}
23 int value_;
26 int called_num = 0;
28 void TestCallback_0() { ++called_num; }
30 void TestCallback_1(int p1) { ++called_num; }
32 void TestCallback_2(int p1, const double* p2) { ++called_num; }
34 void TestCallback_3(int p1, const double* p2, bool* p3) { ++called_num; }
36 void TestCallback_4(int p1, const double* p2, bool* p3, TestParameter p4) {
37 ++called_num;
40 void TestCallback_5(int p1,
41 const double* p2,
42 bool* p3,
43 TestParameter p4,
44 const TestParameter& p5) {
45 ++called_num;
48 typedef proxy::PluginProxyTest ThreadAwareCallbackTest;
50 // Test that a callback created on the main thread will run on the main thread,
51 // even when requested from a different thread.
52 class ThreadAwareCallbackMultiThreadTest
53 : public proxy::PluginProxyMultiThreadTest {
54 public:
55 ThreadAwareCallbackMultiThreadTest() : main_thread_callback_called_(false) {}
56 virtual ~ThreadAwareCallbackMultiThreadTest() {
57 CHECK(main_thread_callback_called_);
60 // proxy::PluginProxyMultiThreadTest implementation.
61 virtual void SetUpTestOnMainThread() OVERRIDE {
62 ProxyAutoLock auto_lock;
64 main_thread_callback_.reset(
65 ThreadAwareCallback<CallbackFunc>::Create(&MainThreadCallbackBody));
68 virtual void SetUpTestOnSecondaryThread() OVERRIDE {
70 ProxyAutoLock auto_lock;
71 main_thread_callback_->RunOnTargetThread(this);
74 PostQuitForSecondaryThread();
75 PostQuitForMainThread();
78 private:
79 typedef void (*CallbackFunc)(ThreadAwareCallbackMultiThreadTest*);
81 static void MainThreadCallbackBody(ThreadAwareCallbackMultiThreadTest* thiz) {
82 thiz->CheckOnThread(MAIN_THREAD);
83 thiz->main_thread_callback_called_ = true;
86 ProxyAutoLock auto_lock;
87 // We have to destroy it prior to the PluginGlobals instance held by the
88 // base class. Otherwise it has a ref to Pepper message loop for the main
89 // thread and the PluginGlobals destructor will complain.
90 thiz->main_thread_callback_.reset(NULL);
94 scoped_ptr<ThreadAwareCallback<CallbackFunc> > main_thread_callback_;
95 bool main_thread_callback_called_;
98 // Test that when a ThreadAwareCallback instance is destroyed, pending tasks to
99 // run the callback will be ignored.
100 class ThreadAwareCallbackAbortTest : public proxy::PluginProxyMultiThreadTest {
101 public:
102 ThreadAwareCallbackAbortTest() {}
103 virtual ~ThreadAwareCallbackAbortTest() {}
105 // proxy::PluginProxyMultiThreadTest implementation.
106 virtual void SetUpTestOnMainThread() OVERRIDE {
107 ProxyAutoLock auto_lock;
109 main_thread_callback_.reset(
110 ThreadAwareCallback<CallbackFunc>::Create(&MainThreadCallbackBody));
113 virtual void SetUpTestOnSecondaryThread() OVERRIDE {
115 ProxyAutoLock auto_lock;
116 main_thread_message_loop_proxy_->PostTask(
117 FROM_HERE,
118 base::Bind(&ThreadAwareCallbackAbortTest::DeleteCallback,
119 base::Unretained(this)));
120 // |main_thread_callback_| is still valid, even if DeleteCallback() can be
121 // called before this following statement. That is because |auto_lock| is
122 // still held by this method, which prevents DeleteCallback() from
123 // deleting the callback.
124 main_thread_callback_->RunOnTargetThread(this);
127 PostQuitForSecondaryThread();
128 PostQuitForMainThread();
131 private:
132 typedef void (*CallbackFunc)(ThreadAwareCallbackAbortTest*);
134 static void MainThreadCallbackBody(ThreadAwareCallbackAbortTest* thiz) {
135 // The callback should not be called.
136 ASSERT_TRUE(false);
139 void DeleteCallback() {
140 ProxyAutoLock auto_lock;
141 main_thread_callback_.reset(NULL);
144 scoped_ptr<ThreadAwareCallback<CallbackFunc> > main_thread_callback_;
147 } // namespace
149 TEST_F(ThreadAwareCallbackTest, Basics) {
150 // ThreadAwareCallback should only be used when the proxy lock has been
151 // acquired.
152 ProxyAutoLock auto_lock;
154 double double_arg = 0.0;
155 bool bool_arg = false;
156 TestParameter object_arg;
158 // Exercise all the template code.
159 called_num = 0;
160 typedef void (*FuncType_0)();
161 scoped_ptr<ThreadAwareCallback<FuncType_0> > callback_0(
162 ThreadAwareCallback<FuncType_0>::Create(TestCallback_0));
163 callback_0->RunOnTargetThread();
165 typedef void (*FuncType_1)(int);
166 scoped_ptr<ThreadAwareCallback<FuncType_1> > callback_1(
167 ThreadAwareCallback<FuncType_1>::Create(TestCallback_1));
168 callback_1->RunOnTargetThread(1);
170 typedef void (*FuncType_2)(int, const double*);
171 scoped_ptr<ThreadAwareCallback<FuncType_2> > callback_2(
172 ThreadAwareCallback<FuncType_2>::Create(TestCallback_2));
173 callback_2->RunOnTargetThread(1, &double_arg);
175 typedef void (*FuncType_3)(int, const double*, bool*);
176 scoped_ptr<ThreadAwareCallback<FuncType_3> > callback_3(
177 ThreadAwareCallback<FuncType_3>::Create(TestCallback_3));
178 callback_3->RunOnTargetThread(1, &double_arg, &bool_arg);
180 typedef void (*FuncType_4)(int, const double*, bool*, TestParameter);
181 scoped_ptr<ThreadAwareCallback<FuncType_4> > callback_4(
182 ThreadAwareCallback<FuncType_4>::Create(TestCallback_4));
183 callback_4->RunOnTargetThread(1, &double_arg, &bool_arg, object_arg);
185 typedef void (*FuncType_5)(
186 int, const double*, bool*, TestParameter, const TestParameter&);
187 scoped_ptr<ThreadAwareCallback<FuncType_5> > callback_5(
188 ThreadAwareCallback<FuncType_5>::Create(TestCallback_5));
189 callback_5->RunOnTargetThread(
190 1, &double_arg, &bool_arg, object_arg, object_arg);
192 EXPECT_EQ(6, called_num);
195 TEST_F(ThreadAwareCallbackMultiThreadTest, RunOnTargetThread) { RunTest(); }
197 TEST_F(ThreadAwareCallbackAbortTest, NotRunIfAborted) { RunTest(); }
199 } // namespace ppapi