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

Side by Side Diff: ppapi/tests/test_case.h

Issue 10910099: PPAPI: Make CompletionCallbacks work right on background threads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add ppb_message_loop_shared.cc/.h Created 8 years, 1 month 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef PPAPI_TESTS_TEST_CASE_H_ 5 #ifndef PPAPI_TESTS_TEST_CASE_H_
6 #define PPAPI_TESTS_TEST_CASE_H_ 6 #define PPAPI_TESTS_TEST_CASE_H_
7 7
8 #include <cmath> 8 #include <cmath>
9 #include <limits> 9 #include <limits>
10 #include <set> 10 #include <set>
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
115 115
116 // Run the given test method on a background thread and return the result. 116 // Run the given test method on a background thread and return the result.
117 template <class T> 117 template <class T>
118 std::string RunOnThread(std::string(T::*test_to_run)()) { 118 std::string RunOnThread(std::string(T::*test_to_run)()) {
119 #ifdef ENABLE_PEPPER_THREADING 119 #ifdef ENABLE_PEPPER_THREADING
120 if (!testing_interface_) { 120 if (!testing_interface_) {
121 return "Testing blocking callbacks requires the testing interface. In " 121 return "Testing blocking callbacks requires the testing interface. In "
122 "Chrome, use the --enable-pepper-testing flag."; 122 "Chrome, use the --enable-pepper-testing flag.";
123 } 123 }
124 // These tests are only valid if running out-of-process (threading is not 124 // These tests are only valid if running out-of-process (threading is not
125 // supported in-process). Just consider it a pass. 125 // supported in-process). For in-process, just consider it a pass.
126 if (!testing_interface_->IsOutOfProcess()) 126 if (!testing_interface_->IsOutOfProcess())
127 return std::string(); 127 return std::string();
128 pp::MessageLoop_Dev background_loop(instance_);
128 ThreadedTestRunner<T> runner(instance_->pp_instance(), 129 ThreadedTestRunner<T> runner(instance_->pp_instance(),
129 static_cast<T*>(this), test_to_run); 130 static_cast<T*>(this), test_to_run, background_loop);
130 RunOnThreadInternal(&ThreadedTestRunner<T>::ThreadFunction, &runner, 131 RunOnThreadInternal(&ThreadedTestRunner<T>::ThreadFunction, &runner,
131 testing_interface_); 132 testing_interface_);
132 return runner.result(); 133 return runner.result();
133 #else 134 #else
134 // If threading's not enabled, just treat it as success. 135 // If threading's not enabled, just treat it as success.
135 return std::string(); 136 return std::string();
136 #endif 137 #endif
137 } 138 }
138 139
139 // Pointer to the instance that owns us. 140 // Pointer to the instance that owns us.
(...skipping 15 matching lines...) Expand all
155 return callback_type_; 156 return callback_type_;
156 } 157 }
157 158
158 private: 159 private:
159 template <class T> 160 template <class T>
160 class ThreadedTestRunner { 161 class ThreadedTestRunner {
161 public: 162 public:
162 typedef std::string(T::*TestMethodType)(); 163 typedef std::string(T::*TestMethodType)();
163 ThreadedTestRunner(PP_Instance instance, 164 ThreadedTestRunner(PP_Instance instance,
164 T* test_case, 165 T* test_case,
165 TestMethodType test_to_run) 166 TestMethodType test_to_run,
167 pp::MessageLoop_Dev loop)
166 : instance_(instance), 168 : instance_(instance),
167 test_case_(test_case), 169 test_case_(test_case),
168 test_to_run_(test_to_run) { 170 test_to_run_(test_to_run),
171 loop_(loop) {
169 } 172 }
170 const std::string& result() { return result_; } 173 const std::string& result() { return result_; }
171 static void ThreadFunction(void* runner) { 174 static void ThreadFunction(void* runner) {
172 static_cast<ThreadedTestRunner<T>*>(runner)->Run(); 175 static_cast<ThreadedTestRunner<T>*>(runner)->Run();
173 } 176 }
174 177
175 private: 178 private:
176 void Run() { 179 void Run() {
177 // TODO(dmichael): Create and attach a pp::MessageLoop for this thread so 180 PP_DCHECK(PP_OK == loop_.AttachToCurrentThread());
178 // nested loops work.
179 result_ = (test_case_->*test_to_run_)(); 181 result_ = (test_case_->*test_to_run_)();
182 // Now give the loop a chance to clean up.
183 loop_.PostQuit(true /* should_destroy */);
184 loop_.Run();
180 // Tell the main thread to quit its nested message loop, now that the test 185 // Tell the main thread to quit its nested message loop, now that the test
181 // is complete. 186 // is complete.
182 TestCase::QuitMainMessageLoop(instance_); 187 TestCase::QuitMainMessageLoop(instance_);
183 } 188 }
184 189
185 std::string result_; 190 std::string result_;
186 PP_Instance instance_; 191 PP_Instance instance_;
187 T* test_case_; 192 T* test_case_;
188 TestMethodType test_to_run_; 193 TestMethodType test_to_run_;
194 pp::MessageLoop_Dev loop_;
189 }; 195 };
190 196
191 // The internals for RunOnThread. This allows us to avoid including 197 // The internals for RunOnThread. This allows us to avoid including
192 // pp_thread.h in this header file, since it includes system headers like 198 // pp_thread.h in this header file, since it includes system headers like
193 // windows.h. 199 // windows.h.
194 // RunOnThreadInternal launches a new thread to run |thread_func|, waits 200 // RunOnThreadInternal launches a new thread to run |thread_func|, waits
195 // for it to complete using RunMessageLoop(), then joins. 201 // for it to complete using RunMessageLoop(), then joins.
196 void RunOnThreadInternal(void (*thread_func)(void*), 202 void RunOnThreadInternal(void (*thread_func)(void*),
197 void* thread_param, 203 void* thread_param,
198 const PPB_Testing_Dev* testing_interface); 204 const PPB_Testing_Dev* testing_interface);
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 CheckResourcesAndVars(Test##name())); \ 274 CheckResourcesAndVars(Test##name())); \
269 } 275 }
270 276
271 #define RUN_TEST_BLOCKING(test_case, name, test_filter) \ 277 #define RUN_TEST_BLOCKING(test_case, name, test_filter) \
272 if (MatchesFilter(#name, test_filter)) { \ 278 if (MatchesFilter(#name, test_filter)) { \
273 set_callback_type(PP_BLOCKING); \ 279 set_callback_type(PP_BLOCKING); \
274 instance_->LogTest(#name"Blocking", \ 280 instance_->LogTest(#name"Blocking", \
275 CheckResourcesAndVars(RunOnThread(&test_case::Test##name))); \ 281 CheckResourcesAndVars(RunOnThread(&test_case::Test##name))); \
276 } 282 }
277 283
284 #define RUN_TEST_BACKGROUND(test_case, name, test_filter) \
285 if (MatchesFilter(#name, test_filter)) { \
286 instance_->LogTest(#name"Background", \
287 CheckResourcesAndVars(RunOnThread(&test_case::Test##name))); \
288 }
289
278 #define RUN_TEST_FORCEASYNC_AND_NOT(name, test_filter) \ 290 #define RUN_TEST_FORCEASYNC_AND_NOT(name, test_filter) \
279 do { \ 291 do { \
280 RUN_TEST_FORCEASYNC(name, test_filter); \ 292 RUN_TEST_FORCEASYNC(name, test_filter); \
281 RUN_TEST(name, test_filter); \ 293 RUN_TEST(name, test_filter); \
282 } while (false) 294 } while (false)
283 295
284 // Run a test with all possible callback types. 296 // Run a test with all possible callback types.
285 #define RUN_CALLBACK_TEST(test_case, name, test_filter) \ 297 #define RUN_CALLBACK_TEST(test_case, name, test_filter) \
286 do { \ 298 do { \
287 RUN_TEST_FORCEASYNC(name, test_filter); \ 299 RUN_TEST_FORCEASYNC(name, test_filter); \
288 RUN_TEST(name, test_filter); \ 300 RUN_TEST(name, test_filter); \
289 RUN_TEST_BLOCKING(test_case, name, test_filter); \ 301 RUN_TEST_BLOCKING(test_case, name, test_filter); \
302 RUN_TEST_BACKGROUND(test_case, name, test_filter); \
290 } while (false) 303 } while (false)
291 304
292 #define RUN_TEST_WITH_REFERENCE_CHECK(name, test_filter) \ 305 #define RUN_TEST_WITH_REFERENCE_CHECK(name, test_filter) \
293 if (MatchesFilter(#name, test_filter)) { \ 306 if (MatchesFilter(#name, test_filter)) { \
294 set_callback_type(PP_OPTIONAL); \ 307 set_callback_type(PP_OPTIONAL); \
295 uint32_t objects = testing_interface_->GetLiveObjectsForInstance( \ 308 uint32_t objects = testing_interface_->GetLiveObjectsForInstance( \
296 instance_->pp_instance()); \ 309 instance_->pp_instance()); \
297 std::string error_message = Test##name(); \ 310 std::string error_message = Test##name(); \
298 if (error_message.empty() && \ 311 if (error_message.empty() && \
299 testing_interface_->GetLiveObjectsForInstance( \ 312 testing_interface_->GetLiveObjectsForInstance( \
(...skipping 20 matching lines...) Expand all
320 #define ASSERT_SUBTEST_SUCCESS(function) \ 333 #define ASSERT_SUBTEST_SUCCESS(function) \
321 do { \ 334 do { \
322 std::string result = (function); \ 335 std::string result = (function); \
323 if (!result.empty()) \ 336 if (!result.empty()) \
324 return result; \ 337 return result; \
325 } while (false) 338 } while (false)
326 339
327 #define PASS() return std::string() 340 #define PASS() return std::string()
328 341
329 #endif // PPAPI_TESTS_TEST_CASE_H_ 342 #endif // PPAPI_TESTS_TEST_CASE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698