OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 #include <stddef.h> | 5 #include <stddef.h> |
6 #include <stdint.h> | 6 #include <stdint.h> |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 1037 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1048 thread_safe_sender); | 1048 thread_safe_sender); |
1049 other_thread.message_loop()->task_runner()->PostTask(FROM_HERE, run_method); | 1049 other_thread.message_loop()->task_runner()->PostTask(FROM_HERE, run_method); |
1050 | 1050 |
1051 // Block until the method callback is called on the background thread. | 1051 // Block until the method callback is called on the background thread. |
1052 run_loop.Run(); | 1052 run_loop.Run(); |
1053 } | 1053 } |
1054 | 1054 |
1055 struct ForwarderTestContext { | 1055 struct ForwarderTestContext { |
1056 IntegerSenderConnectionPtr connection_ptr; | 1056 IntegerSenderConnectionPtr connection_ptr; |
1057 std::unique_ptr<IntegerSenderConnectionImpl> interface_impl; | 1057 std::unique_ptr<IntegerSenderConnectionImpl> interface_impl; |
| 1058 IntegerSenderAssociatedRequest sender_request; |
1058 }; | 1059 }; |
1059 | 1060 |
1060 TEST_F(AssociatedInterfaceTest, BindLaterThreadSafeAssociatedInterfacePtr) { | 1061 TEST_F(AssociatedInterfaceTest, |
| 1062 ThreadSafeAssociatedInterfacePtrWithTaskRunner) { |
1061 // Start the thread from where we'll bind the interface pointer. | 1063 // Start the thread from where we'll bind the interface pointer. |
1062 base::Thread other_thread("service test thread"); | 1064 base::Thread other_thread("service test thread"); |
1063 other_thread.Start(); | 1065 other_thread.Start(); |
1064 const scoped_refptr<base::SingleThreadTaskRunner>& other_thread_task_runner = | 1066 const scoped_refptr<base::SingleThreadTaskRunner>& other_thread_task_runner = |
1065 other_thread.message_loop()->task_runner(); | 1067 other_thread.message_loop()->task_runner(); |
| 1068 |
1066 ForwarderTestContext* context = new ForwarderTestContext(); | 1069 ForwarderTestContext* context = new ForwarderTestContext(); |
1067 | 1070 IntegerSenderAssociatedPtrInfo sender_info; |
1068 base::WaitableEvent echo_called_event( | 1071 base::WaitableEvent sender_info_bound_event( |
1069 base::WaitableEvent::ResetPolicy::MANUAL, | 1072 base::WaitableEvent::ResetPolicy::MANUAL, |
1070 base::WaitableEvent::InitialState::NOT_SIGNALED); | 1073 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 1074 auto setup = [](base::WaitableEvent* sender_info_bound_event, |
| 1075 IntegerSenderAssociatedPtrInfo* sender_info, |
| 1076 ForwarderTestContext* context) { |
| 1077 context->interface_impl = base::MakeUnique<IntegerSenderConnectionImpl>( |
| 1078 MakeRequest(&context->connection_ptr)); |
1071 | 1079 |
1072 // Create a ThreadSafeAssociatedPtr that we'll bind from a different thread. | 1080 IntegerSenderAssociatedPtr sender; |
| 1081 IntegerSenderAssociatedRequest sender_request = |
| 1082 MakeRequest(&sender, context->connection_ptr.associated_group()); |
| 1083 *sender_info = sender.PassInterface(); |
| 1084 |
| 1085 context->connection_ptr->GetSender(std::move(sender_request)); |
| 1086 |
| 1087 // Unblock the main thread as soon as |sender_info| is set. |
| 1088 sender_info_bound_event->Signal(); |
| 1089 }; |
| 1090 other_thread_task_runner->PostTask( |
| 1091 FROM_HERE, |
| 1092 base::Bind(setup, &sender_info_bound_event, &sender_info, context)); |
| 1093 sender_info_bound_event.Wait(); |
| 1094 |
| 1095 // Create a ThreadSafeAssociatedPtr that binds on the background thread and is |
| 1096 // associated with |connection_ptr| there. |
1073 scoped_refptr<ThreadSafeIntegerSenderAssociatedPtr> thread_safe_ptr = | 1097 scoped_refptr<ThreadSafeIntegerSenderAssociatedPtr> thread_safe_ptr = |
1074 ThreadSafeIntegerSenderAssociatedPtr::CreateUnbound( | 1098 ThreadSafeIntegerSenderAssociatedPtr::Create(std::move(sender_info), |
1075 other_thread_task_runner); | 1099 other_thread_task_runner); |
1076 | 1100 |
1077 base::RunLoop bind_run_loop; | 1101 // Issue a call on the thread-safe ptr immediately. Note that this may happen |
1078 auto run_method = base::Bind( | 1102 // before the interface is bound on the background thread, and that must be |
1079 [](base::WaitableEvent* echo_called_event, | 1103 // OK. |
1080 const scoped_refptr<ThreadSafeIntegerSenderAssociatedPtr>& | |
1081 thread_safe_ptr, | |
1082 ForwarderTestContext* context) { | |
1083 // Wait for echo to be called on the main thread so the interface method | |
1084 // call happens before the bind. | |
1085 echo_called_event->Wait(); | |
1086 | |
1087 // We are on the background thread, create the interface ptr. | |
1088 context->interface_impl = | |
1089 base::MakeUnique<IntegerSenderConnectionImpl>( | |
1090 MakeRequest(&(context->connection_ptr))); | |
1091 IntegerSenderAssociatedPtr sender; | |
1092 context->connection_ptr->GetSender( | |
1093 MakeRequest(&sender, context->connection_ptr.associated_group())); | |
1094 thread_safe_ptr->Bind(std::move(sender)); | |
1095 }, | |
1096 &echo_called_event, thread_safe_ptr, context); | |
1097 | |
1098 other_thread_task_runner->PostTask(FROM_HERE, run_method); | |
1099 | |
1100 { | 1104 { |
1101 // Now we can call methods on the interface from the main thread. | |
1102 auto echo_callback = | 1105 auto echo_callback = |
1103 base::Bind([](const base::Closure& quit_closure, int32_t result) { | 1106 base::Bind([](const base::Closure& quit_closure, int32_t result) { |
1104 EXPECT_EQ(123, result); | 1107 EXPECT_EQ(123, result); |
1105 quit_closure.Run(); | 1108 quit_closure.Run(); |
1106 }); | 1109 }); |
1107 base::RunLoop run_loop; | 1110 base::RunLoop run_loop; |
1108 (*thread_safe_ptr) | 1111 (*thread_safe_ptr) |
1109 ->Echo(123, base::Bind(echo_callback, run_loop.QuitClosure())); | 1112 ->Echo(123, base::Bind(echo_callback, run_loop.QuitClosure())); |
1110 | 1113 |
1111 // Let the bind happen on the background thread. | |
1112 echo_called_event.Signal(); | |
1113 | |
1114 // Block until the method callback is called. | 1114 // Block until the method callback is called. |
1115 run_loop.Run(); | 1115 run_loop.Run(); |
1116 } | 1116 } |
1117 | 1117 |
1118 other_thread_task_runner->DeleteSoon(FROM_HERE, context); | 1118 other_thread_task_runner->DeleteSoon(FROM_HERE, context); |
1119 | 1119 |
1120 // Reset the pointer now so the InterfacePtr associated resources can be | 1120 // Reset the pointer now so the InterfacePtr associated resources can be |
1121 // deleted before the background thread's message loop is invalidated. | 1121 // deleted before the background thread's message loop is invalidated. |
1122 thread_safe_ptr = nullptr; | 1122 thread_safe_ptr = nullptr; |
1123 } | 1123 } |
(...skipping 17 matching lines...) Expand all Loading... |
1141 provider->GetPing( | 1141 provider->GetPing( |
1142 mojo::MakeRequest(&ping, provider.associated_group())); | 1142 mojo::MakeRequest(&ping, provider.associated_group())); |
1143 base::RunLoop run_loop; | 1143 base::RunLoop run_loop; |
1144 ping.set_connection_error_handler(run_loop.QuitClosure()); | 1144 ping.set_connection_error_handler(run_loop.QuitClosure()); |
1145 run_loop.Run(); | 1145 run_loop.Run(); |
1146 } | 1146 } |
1147 | 1147 |
1148 } // namespace | 1148 } // namespace |
1149 } // namespace test | 1149 } // namespace test |
1150 } // namespace mojo | 1150 } // namespace mojo |
OLD | NEW |