Index: ppapi/tests/test_post_message.cc |
diff --git a/ppapi/tests/test_post_message.cc b/ppapi/tests/test_post_message.cc |
index 02ebed6bf6fd9893758110a9723a739d6125fb8d..dee87d2402645bb8170d16e49fd3128ae7694f85 100644 |
--- a/ppapi/tests/test_post_message.cc |
+++ b/ppapi/tests/test_post_message.cc |
@@ -11,6 +11,7 @@ |
#include "ppapi/cpp/dev/scriptable_object_deprecated.h" |
#include "ppapi/cpp/instance.h" |
#include "ppapi/cpp/var.h" |
+#include "ppapi/tests/pp_thread.h" |
#include "ppapi/tests/test_utils.h" |
#include "ppapi/tests/testing_instance.h" |
@@ -29,6 +30,25 @@ const int32_t kTestInt = 42; |
const double kTestDouble = 42.0; |
const int32_t kThreadsToRun = 10; |
+#if defined(PPAPI_HAS_POSIX_THREADS) |
+// The struct that invoke_post_message_thread_func expects for its argument. |
+// It includes the instance on which to invoke PostMessage, and the value to |
+// pass to PostMessage. |
+struct InvokePostMessageThreadArg { |
+ InvokePostMessageThreadArg(pp::Instance* i, const pp::Var& v) |
+ : instance(i), value_to_send(v) {} |
+ pp::Instance* instance; |
+ pp::Var value_to_send; |
+}; |
+ |
+void InvokePostMessageThreadFunc(void* user_data) { |
+ InvokePostMessageThreadArg* arg( |
+ static_cast<InvokePostMessageThreadArg*>(user_data)); |
+ arg->instance->PostMessage(arg->value_to_send); |
+ delete arg; |
+} |
+#endif |
+ |
} // namespace |
bool TestPostMessage::Init() { |
@@ -40,6 +60,8 @@ void TestPostMessage::RunTest() { |
RUN_TEST(MessageEvent); |
RUN_TEST(NoHandler); |
RUN_TEST(ExtraParam); |
+ if (testing_interface_->IsOutOfProcess()) |
+ RUN_TEST(NonMainThread); |
} |
void TestPostMessage::HandleMessage(const pp::Var& message_data) { |
@@ -254,3 +276,73 @@ std::string TestPostMessage::TestExtraParam() { |
PASS(); |
} |
+std::string TestPostMessage::TestNonMainThread() { |
+ // Set up the JavaScript onmessage handler to echo the data part of the |
+ // message event back to us. |
+ // Delete any lingering event listeners. |
+ ASSERT_TRUE(ClearListeners()); |
+ // Add a listener that will respond with 1 and an empty array (where the |
+ // message port array would appear if it was Worker postMessage). |
+ ASSERT_TRUE(AddEchoingListener("message_event.data")); |
+ |
+ message_data_.clear(); |
+ |
+#if defined(PPAPI_HAS_POSIX_THREADS) |
+ // Set up a thread for each integer from 0 to (kThreadsToRun - 1). Make each |
+ // thread send the number that matches its index. For good measure, call |
+ // postMessage from the main thread with numbers kThreadsToRun to |
+ // (kThreadsToRun * 2 - 1). At the end, we make sure we got all the numbers |
+ // we expected. |
+ PP_ThreadType threads[kThreadsToRun]; |
+ for (int32_t i = 0; i < kThreadsToRun; ++i) { |
+ // Set up a thread to send a value of i |
+ void* arg = new InvokePostMessageThreadArg(instance_, pp::Var(i)); |
+ PP_CreateThread(&threads[i], &InvokePostMessageThreadFunc, arg); |
+ |
+ // Invoke PostMessage right now to send a value of (kThreadsToRun + i). |
+ instance_->PostMessage(pp::Var(kThreadsToRun + i)); |
+ } |
+ |
+ // Now join all threads. |
+ for (int32_t i = 0; i < kThreadsToRun; ++i) { |
+ PP_JoinThread(threads[i]); |
+ } |
+ |
+ // PostMessage is asynchronous, so we should not receive a response yet. |
+ ASSERT_EQ(message_data_.size(), 0); |
+ |
+ // Make sure we got all values that we expected. Note that because it's legal |
+ // for the JavaScript engine to treat our integers as floating points, we |
+ // can't just use std::find or equality comparison. So we first put the |
+ // integer version of all the received Vars in to received_ints, and build up |
+ // expected_ints. After the loop, we can sort received_int (they may come out |
+ // of order) and compare to the expected_ints. |
+ int32_t expected_num = 2 * kThreadsToRun; |
+ std::vector<int32_t> expected_ints; |
+ std::vector<int32_t> received_ints; |
+ for (int32_t i = 0; i < expected_num; ++i) { |
+ expected_ints.push_back(i); |
+ |
+ // Run the message loop to get the next expected message. |
+ testing_interface_->RunMessageLoop(instance_->pp_instance()); |
+ // Make sure we got another message in. |
+ ASSERT_EQ(message_data_.size(), static_cast<size_t>(i+1)); |
+ |
+ if (message_data_[i].is_int()) { |
+ received_ints.push_back(message_data_[i].AsInt()); |
+ } else if (message_data_[i].is_double()) { |
+ received_ints.push_back( |
+ static_cast<int32_t>(message_data_[i].AsDouble() + 0.5)); |
+ } |
+ } |
+ // Check the size again, in case we received any non-numeric types that we |
+ // didn't add to our int32_t vector. |
+ ASSERT_EQ(received_ints.size(), expected_ints.size()); |
+ // Now sort received_ints; we have no guarantee as to the order in which we |
+ // received them. |
+ std::sort(received_ints.begin(), received_ints.end()); |
+ ASSERT_EQ(received_ints, expected_ints); |
+#endif |
+ PASS(); |
+} |
+ |