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

Side by Side 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 unified diff | Download patch | Annotate | Revision Log
« 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 »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
5 #include "ppapi/shared_impl/thread_aware_callback.h"
6
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"
14
15 namespace ppapi {
16
17 namespace {
18
19 class TestParameter {
20 public:
21 TestParameter() : value_(0) {
22 }
23
24 int value_;
25 };
26
27 int called_num = 0;
28
29 void TestCallback_0() {
30 ++called_num;
31 }
32
33 void TestCallback_1(int p1) {
34 ++called_num;
35 }
36
37 void TestCallback_2(int p1, const double* p2) {
38 ++called_num;
39 }
40
41 void TestCallback_3(int p1, const double* p2, bool* p3) {
42 ++called_num;
43 }
44
45 void TestCallback_4(int p1, const double* p2, bool* p3, TestParameter p4) {
46 ++called_num;
47 }
48
49 void TestCallback_5(int p1,
50 const double* p2,
51 bool* p3,
52 TestParameter p4,
53 const TestParameter& p5) {
54 ++called_num;
55 }
56
57 typedef proxy::PluginProxyTest ThreadAwareCallbackTest;
58
59 // Test that a callback created on the main thread will run on the main thread,
60 // even when requested from a different thread.
61 class ThreadAwareCallbackMultiThreadTest
62 : public proxy::PluginProxyMultiThreadTest {
63 public:
64 ThreadAwareCallbackMultiThreadTest() : main_thread_callback_called_(false) {
65 }
66 virtual ~ThreadAwareCallbackMultiThreadTest() {
67 CHECK(main_thread_callback_called_);
68 }
69
70 // proxy::PluginProxyMultiThreadTest implementation.
71 virtual void SetUpTestOnMainThread() OVERRIDE {
72 ProxyAutoLock auto_lock;
73
74 main_thread_callback_.reset(
75 ThreadAwareCallback<CallbackFunc>::Create(&MainThreadCallbackBody));
76 }
77
78 virtual void SetUpTestOnSecondaryThread() OVERRIDE {
79 {
80 ProxyAutoLock auto_lock;
81 main_thread_callback_->RunOnTargetThread(this);
82 }
83
84 PostQuitForSecondaryThread();
85 PostQuitForMainThread();
86 }
87
88 private:
89 typedef void (*CallbackFunc)(ThreadAwareCallbackMultiThreadTest*);
90
91 static void MainThreadCallbackBody(ThreadAwareCallbackMultiThreadTest* thiz) {
92 thiz->CheckOnThread(MAIN_THREAD);
93 thiz->main_thread_callback_called_ = true;
94
95 {
96 ProxyAutoLock auto_lock;
97 // We have to destroy it prior to the PluginGlobals instance held by the
98 // base class. Otherwise it has a ref to Pepper message loop for the main
99 // thread and the PluginGlobals destructor will complain.
100 thiz->main_thread_callback_.reset(NULL);
101 }
102 }
103
104 scoped_ptr<ThreadAwareCallback<CallbackFunc> > main_thread_callback_;
105 bool main_thread_callback_called_;
106 };
107
108 // Test that when a ThreadAwareCallback instance is destroyed, pending tasks to
109 // run the callback will be ignored.
110 class ThreadAwareCallbackAbortTest : public proxy::PluginProxyMultiThreadTest {
111 public:
112 ThreadAwareCallbackAbortTest() {
113 }
114 virtual ~ThreadAwareCallbackAbortTest() {
115 }
116
117 // proxy::PluginProxyMultiThreadTest implementation.
118 virtual void SetUpTestOnMainThread() OVERRIDE {
119 ProxyAutoLock auto_lock;
120
121 main_thread_callback_.reset(
122 ThreadAwareCallback<CallbackFunc>::Create(&MainThreadCallbackBody));
123 }
124
125 virtual void SetUpTestOnSecondaryThread() OVERRIDE {
126 {
127 ProxyAutoLock auto_lock;
128 main_thread_message_loop_proxy_->PostTask(
129 FROM_HERE,
130 base::Bind(&ThreadAwareCallbackAbortTest::DeleteCallback,
131 base::Unretained(this)));
132 // |main_thread_callback_| is still valid, even if DeleteCallback() can be
133 // called before this following statement. That is because |auto_lock| is
134 // still held by this method, which prevents DeleteCallback() from
135 // deleting the callback.
136 main_thread_callback_->RunOnTargetThread(this);
137 }
138
139 PostQuitForSecondaryThread();
140 PostQuitForMainThread();
141 }
142
143 private:
144 typedef void (*CallbackFunc)(ThreadAwareCallbackAbortTest*);
145
146 static void MainThreadCallbackBody(ThreadAwareCallbackAbortTest* thiz) {
147 // The callback should not be called.
148 ASSERT_TRUE(false);
149 }
150
151 void DeleteCallback() {
152 ProxyAutoLock auto_lock;
153 main_thread_callback_.reset(NULL);
154 }
155
156 scoped_ptr<ThreadAwareCallback<CallbackFunc> > main_thread_callback_;
157 };
158
159 } // namespace
160
161 TEST_F(ThreadAwareCallbackTest, Basics) {
162 // ThreadAwareCallback should only be used when the proxy lock has been
163 // acquired.
164 ProxyAutoLock auto_lock;
165
166 double double_arg = 0.0;
167 bool bool_arg = false;
168 TestParameter object_arg;
169
170 // Exercise all the template code.
171 called_num = 0;
172 typedef void (*FuncType_0)();
173 scoped_ptr<ThreadAwareCallback<FuncType_0> > callback_0(
174 ThreadAwareCallback<FuncType_0>::Create(TestCallback_0));
175 callback_0->RunOnTargetThread();
176
177 typedef void (*FuncType_1)(int);
178 scoped_ptr<ThreadAwareCallback<FuncType_1> > callback_1(
179 ThreadAwareCallback<FuncType_1>::Create(TestCallback_1));
180 callback_1->RunOnTargetThread(1);
181
182 typedef void (*FuncType_2)(int, const double*);
183 scoped_ptr<ThreadAwareCallback<FuncType_2> > callback_2(
184 ThreadAwareCallback<FuncType_2>::Create(TestCallback_2));
185 callback_2->RunOnTargetThread(1, &double_arg);
186
187 typedef void (*FuncType_3)(int, const double*, bool*);
188 scoped_ptr<ThreadAwareCallback<FuncType_3> > callback_3(
189 ThreadAwareCallback<FuncType_3>::Create(TestCallback_3));
190 callback_3->RunOnTargetThread(1, &double_arg, &bool_arg);
191
192 typedef void (*FuncType_4)(int, const double*, bool*, TestParameter);
193 scoped_ptr<ThreadAwareCallback<FuncType_4> > callback_4(
194 ThreadAwareCallback<FuncType_4>::Create(TestCallback_4));
195 callback_4->RunOnTargetThread(1, &double_arg, &bool_arg, object_arg);
196
197 typedef void (*FuncType_5)(int,
198 const double*,
199 bool*,
200 TestParameter,
201 const TestParameter&);
202 scoped_ptr<ThreadAwareCallback<FuncType_5> > callback_5(
203 ThreadAwareCallback<FuncType_5>::Create(TestCallback_5));
204 callback_5->RunOnTargetThread(1, &double_arg, &bool_arg, object_arg,
205 object_arg);
206
207 EXPECT_EQ(6, called_num);
208 }
209
210 TEST_F(ThreadAwareCallbackMultiThreadTest, RunOnTargetThread) {
211 RunTest();
212 }
213
214 TEST_F(ThreadAwareCallbackAbortTest, NotRunIfAborted) {
215 RunTest();
216 }
217
218 } // namespace ppapi
OLDNEW
« 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