summaryrefslogtreecommitdiffstats
path: root/ppapi/tests
diff options
context:
space:
mode:
authordmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-08 18:55:16 +0000
committerdmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-08 18:55:16 +0000
commit77c3417c441feac4bdcbad88f5a6bbf7f77bfe8f (patch)
treede665a63fc4d8137139cb976a45a938fc02b0d72 /ppapi/tests
parente92a3618d401cd78886f0a404aa28a7e7947bc37 (diff)
downloadchromium_src-77c3417c441feac4bdcbad88f5a6bbf7f77bfe8f.zip
chromium_src-77c3417c441feac4bdcbad88f5a6bbf7f77bfe8f.tar.gz
chromium_src-77c3417c441feac4bdcbad88f5a6bbf7f77bfe8f.tar.bz2
PPAPI: Make CompletionCallbacks work right on background threads.
Now, TrackedCallback::Run will: -Run the callback immediately if it is on the right thread. -PostRun to the correct thread if it is not. This was preceded by https://chromiumcodereview.appspot.com/10909244/, which removed ClearAndRun and does some other little cleanups to TrackedCallback to make it usable on background threads. BUG=92909 Review URL: https://chromiumcodereview.appspot.com/10910099 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@166719 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/tests')
-rw-r--r--ppapi/tests/test_case.h25
-rw-r--r--ppapi/tests/test_utils.cc37
-rw-r--r--ppapi/tests/test_utils.h4
3 files changed, 57 insertions, 9 deletions
diff --git a/ppapi/tests/test_case.h b/ppapi/tests/test_case.h
index 2cf2ddf..aa35046 100644
--- a/ppapi/tests/test_case.h
+++ b/ppapi/tests/test_case.h
@@ -122,11 +122,12 @@ class TestCase {
"Chrome, use the --enable-pepper-testing flag.";
}
// These tests are only valid if running out-of-process (threading is not
- // supported in-process). Just consider it a pass.
+ // supported in-process). For in-process, just consider it a pass.
if (!testing_interface_->IsOutOfProcess())
return std::string();
+ pp::MessageLoop_Dev background_loop(instance_);
ThreadedTestRunner<T> runner(instance_->pp_instance(),
- static_cast<T*>(this), test_to_run);
+ static_cast<T*>(this), test_to_run, background_loop);
RunOnThreadInternal(&ThreadedTestRunner<T>::ThreadFunction, &runner,
testing_interface_);
return runner.result();
@@ -162,10 +163,12 @@ class TestCase {
typedef std::string(T::*TestMethodType)();
ThreadedTestRunner(PP_Instance instance,
T* test_case,
- TestMethodType test_to_run)
+ TestMethodType test_to_run,
+ pp::MessageLoop_Dev loop)
: instance_(instance),
test_case_(test_case),
- test_to_run_(test_to_run) {
+ test_to_run_(test_to_run),
+ loop_(loop) {
}
const std::string& result() { return result_; }
static void ThreadFunction(void* runner) {
@@ -174,9 +177,11 @@ class TestCase {
private:
void Run() {
- // TODO(dmichael): Create and attach a pp::MessageLoop for this thread so
- // nested loops work.
+ PP_DCHECK(PP_OK == loop_.AttachToCurrentThread());
result_ = (test_case_->*test_to_run_)();
+ // Now give the loop a chance to clean up.
+ loop_.PostQuit(true /* should_destroy */);
+ loop_.Run();
// Tell the main thread to quit its nested message loop, now that the test
// is complete.
TestCase::QuitMainMessageLoop(instance_);
@@ -186,6 +191,7 @@ class TestCase {
PP_Instance instance_;
T* test_case_;
TestMethodType test_to_run_;
+ pp::MessageLoop_Dev loop_;
};
// The internals for RunOnThread. This allows us to avoid including
@@ -275,6 +281,12 @@ class TestCaseFactory {
CheckResourcesAndVars(RunOnThread(&test_case::Test##name))); \
}
+#define RUN_TEST_BACKGROUND(test_case, name, test_filter) \
+ if (MatchesFilter(#name, test_filter)) { \
+ instance_->LogTest(#name"Background", \
+ CheckResourcesAndVars(RunOnThread(&test_case::Test##name))); \
+ }
+
#define RUN_TEST_FORCEASYNC_AND_NOT(name, test_filter) \
do { \
RUN_TEST_FORCEASYNC(name, test_filter); \
@@ -287,6 +299,7 @@ class TestCaseFactory {
RUN_TEST_FORCEASYNC(name, test_filter); \
RUN_TEST(name, test_filter); \
RUN_TEST_BLOCKING(test_case, name, test_filter); \
+ RUN_TEST_BACKGROUND(test_case, name, test_filter); \
} while (false)
#define RUN_TEST_WITH_REFERENCE_CHECK(name, test_filter) \
diff --git a/ppapi/tests/test_utils.cc b/ppapi/tests/test_utils.cc
index 9776e34..20a8a81 100644
--- a/ppapi/tests/test_utils.cc
+++ b/ppapi/tests/test_utils.cc
@@ -13,6 +13,7 @@
#endif
#include "ppapi/c/pp_errors.h"
+#include "ppapi/cpp/dev/message_loop_dev.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/var.h"
@@ -138,7 +139,7 @@ int32_t TestCompletionCallback::WaitForResult() {
errors_.clear();
if (!have_result_) {
post_quit_task_ = true;
- GetTestingInterface()->RunMessageLoop(instance_);
+ RunMessageLoop();
}
return result_;
}
@@ -150,7 +151,7 @@ void TestCompletionCallback::WaitForResult(int32_t result) {
if (result == PP_OK_COMPLETIONPENDING) {
if (!have_result_) {
post_quit_task_ = true;
- GetTestingInterface()->RunMessageLoop(instance_);
+ RunMessageLoop();
}
if (callback_type_ == PP_BLOCKING) {
errors_.assign(
@@ -200,6 +201,7 @@ pp::CompletionCallback TestCompletionCallback::GetCallback() {
return pp::CompletionCallback();
else if (callback_type_ == PP_OPTIONAL)
flags = PP_COMPLETIONCALLBACK_FLAG_OPTIONAL;
+ target_loop_ = pp::MessageLoop_Dev::GetCurrent();
return pp::CompletionCallback(&TestCompletionCallback::Handler,
const_cast<TestCompletionCallback*>(this),
flags);
@@ -229,7 +231,36 @@ void TestCompletionCallback::Handler(void* user_data, int32_t result) {
callback->delegate_->OnCallback(user_data, result);
if (callback->post_quit_task_) {
callback->post_quit_task_ = false;
- GetTestingInterface()->QuitMessageLoop(callback->instance_);
+ callback->QuitMessageLoop();
+ }
+ if (callback->target_loop_ != pp::MessageLoop_Dev::GetCurrent()) {
+ // Note, in-process, loop_ and GetCurrent() will both be NULL, so should
+ // still be equal.
+ callback->errors_.assign(
+ ReportError("TestCompletionCallback: Callback ran on the wrong message "
+ "loop!",
+ result));
}
}
+void TestCompletionCallback::RunMessageLoop() {
+ pp::MessageLoop_Dev loop(pp::MessageLoop_Dev::GetCurrent());
+ // If we don't have a message loop, we're probably running in process, where
+ // PPB_MessageLoop is not supported. Just use the Testing message loop.
+ if (loop.is_null() || loop == pp::MessageLoop_Dev::GetForMainThread())
+ GetTestingInterface()->RunMessageLoop(instance_);
+ else
+ loop.Run();
+}
+
+void TestCompletionCallback::QuitMessageLoop() {
+ pp::MessageLoop_Dev loop(pp::MessageLoop_Dev::GetCurrent());
+ // If we don't have a message loop, we're probably running in process, where
+ // PPB_MessageLoop is not supported. Just use the Testing message loop.
+ if (loop.is_null() || loop == pp::MessageLoop_Dev::GetForMainThread()) {
+ GetTestingInterface()->QuitMessageLoop(instance_);
+ } else {
+ const bool should_quit = false;
+ loop.PostQuit(should_quit);
+ }
+}
diff --git a/ppapi/tests/test_utils.h b/ppapi/tests/test_utils.h
index ab87dd3..60f7fc4 100644
--- a/ppapi/tests/test_utils.h
+++ b/ppapi/tests/test_utils.h
@@ -11,6 +11,7 @@
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_stdint.h"
#include "ppapi/cpp/completion_callback.h"
+#include "ppapi/cpp/dev/message_loop_dev.h"
#include "ppapi/utility/completion_callback_factory.h"
// Timeout to wait for some action to complete.
@@ -152,6 +153,8 @@ class TestCompletionCallback {
private:
static void Handler(void* user_data, int32_t result);
+ void RunMessageLoop();
+ void QuitMessageLoop();
// Used to check that WaitForResult is only called once for each usage of the
// callback.
@@ -166,6 +169,7 @@ class TestCompletionCallback {
unsigned run_count_;
PP_Instance instance_;
Delegate* delegate_;
+ pp::MessageLoop_Dev target_loop_;
};
// Verifies that the callback didn't record any errors. If the callback is run