Index: ppapi/tests/test_message_loop.cc |
diff --git a/ppapi/tests/test_message_loop.cc b/ppapi/tests/test_message_loop.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..49845fb33a07ba4c80c51c5af8785b6f44d0ae78 |
--- /dev/null |
+++ b/ppapi/tests/test_message_loop.cc |
@@ -0,0 +1,105 @@ |
+// 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/tests/test_message_loop.h" |
+ |
+#include "ppapi/c/pp_macros.h" |
+#include "ppapi/cpp/core.h" |
+#include "ppapi/cpp/logging.h" |
+#include "ppapi/cpp/module.h" |
+#include "ppapi/cpp/dev/message_loop_dev.h" |
+#include "ppapi/tests/testing_instance.h" |
+#include "ppapi/utility/threading/simple_thread.h" |
+ |
+REGISTER_TEST_CASE(MessageLoop); |
+ |
+TestMessageLoop::TestMessageLoop(TestingInstance* instance) |
+ : TestCase(instance), |
+ param_(kInvalid), |
+ PP_ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)), |
+ main_loop_task_ran_(instance->pp_instance()) { |
+} |
+ |
+TestMessageLoop::~TestMessageLoop() { |
+} |
+ |
+void TestMessageLoop::RunTests(const std::string& filter) { |
+ RUN_TEST(Basics, filter); |
+ RUN_TEST(Post, filter); |
+} |
+ |
+std::string TestMessageLoop::TestBasics() { |
+ // The main thread message loop should be valid, and equal to the "current" |
+ // one. |
+ ASSERT_NE(0, pp::MessageLoop_Dev::GetForMainThread().pp_resource()); |
+ ASSERT_EQ(pp::MessageLoop_Dev::GetForMainThread().pp_resource(), |
+ pp::MessageLoop_Dev::GetCurrent().pp_resource()); |
+ |
+ // We shouldn't be able to attach a new loop to the main thread. |
+ pp::MessageLoop_Dev loop(instance_); |
+ ASSERT_EQ(PP_ERROR_INPROGRESS, loop.AttachToCurrentThread()); |
+ |
+ // Nested loops aren't allowed. |
+ ASSERT_EQ(PP_ERROR_INPROGRESS, |
+ pp::MessageLoop_Dev::GetForMainThread().Run()); |
+ |
+ // We can't run on a loop that isn't attached to a thread. |
+ ASSERT_EQ(PP_ERROR_WRONG_THREAD, loop.Run()); |
+ |
+ PASS(); |
+} |
+ |
+std::string TestMessageLoop::TestPost() { |
+ // Make sure we can post a task from the main thread back to the main thread. |
+ pp::MessageLoop_Dev::GetCurrent().PostWork(callback_factory_.NewCallback( |
+ &TestMessageLoop::SetParamAndQuitTask, kMainToMain)); |
+ main_loop_task_ran_.Wait(); |
+ ASSERT_EQ(param_, kMainToMain); |
+ main_loop_task_ran_.Reset(); |
+ |
+ pp::SimpleThread thread(instance_); |
+ // Post a task before the thread is started, to make sure it is run. |
+ // TODO(dmichael): CompletionCallbackFactory is not 100% thread safe for |
+ // posting tasks to a thread other than where the factory was created. It |
+ // should be OK for this test, since we know that the |
+ // CompletionCallbackFactory and its target object outlive all callbacks. But |
+ // developers are likely to misuse CompletionCallbackFactory. Maybe we should |
+ // make it safe to use a callback on another thread? |
+ thread.message_loop().PostWork(callback_factory_.NewCallback( |
+ &TestMessageLoop::EchoParamToMainTask, kBeforeStart)); |
+ ASSERT_TRUE(thread.Start()); |
+ main_loop_task_ran_.Wait(); |
+ ASSERT_EQ(param_, kBeforeStart); |
+ main_loop_task_ran_.Reset(); |
+ |
+ // Now post another one after start. This is the more normal case. |
+ |
+ // Nested loops aren't allowed. |
+ ASSERT_EQ(PP_ERROR_INPROGRESS, |
+ pp::MessageLoop_Dev::GetForMainThread().Run()); |
+ thread.message_loop().PostWork(callback_factory_.NewCallback( |
+ &TestMessageLoop::EchoParamToMainTask, kAfterStart)); |
+ main_loop_task_ran_.Wait(); |
+ ASSERT_EQ(param_, kAfterStart); |
+ main_loop_task_ran_.Reset(); |
+ |
+ // Quit and join the thread. |
+ ASSERT_TRUE(thread.Join()); |
+ |
+ PASS(); |
+} |
+ |
+void TestMessageLoop::SetParamAndQuitTask(int32_t result, TestParam param) { |
+ PP_DCHECK(result == PP_OK); |
+ param_ = param; |
+ main_loop_task_ran_.Signal(); |
+} |
+ |
+void TestMessageLoop::EchoParamToMainTask(int32_t result, TestParam param) { |
+ PP_DCHECK(result == PP_OK); |
+ pp::MessageLoop_Dev::GetForMainThread().PostWork( |
+ callback_factory_.NewCallback( |
+ &TestMessageLoop::SetParamAndQuitTask, param)); |
+} |
+ |