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" |
11 #include "base/callback.h" | 11 #include "base/callback.h" |
12 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.h" |
13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
14 #include "base/message_loop/message_loop.h" | 14 #include "base/message_loop/message_loop.h" |
15 #include "base/run_loop.h" | 15 #include "base/run_loop.h" |
16 #include "base/single_thread_task_runner.h" | 16 #include "base/single_thread_task_runner.h" |
| 17 #include "base/synchronization/waitable_event.h" |
17 #include "base/threading/sequenced_task_runner_handle.h" | 18 #include "base/threading/sequenced_task_runner_handle.h" |
18 #include "base/threading/thread.h" | 19 #include "base/threading/thread.h" |
19 #include "base/threading/thread_task_runner_handle.h" | 20 #include "base/threading/thread_task_runner_handle.h" |
20 #include "mojo/public/cpp/bindings/associated_binding.h" | 21 #include "mojo/public/cpp/bindings/associated_binding.h" |
21 #include "mojo/public/cpp/bindings/associated_group.h" | 22 #include "mojo/public/cpp/bindings/associated_group.h" |
22 #include "mojo/public/cpp/bindings/associated_interface_ptr.h" | 23 #include "mojo/public/cpp/bindings/associated_interface_ptr.h" |
23 #include "mojo/public/cpp/bindings/associated_interface_ptr_info.h" | 24 #include "mojo/public/cpp/bindings/associated_interface_ptr_info.h" |
24 #include "mojo/public/cpp/bindings/associated_interface_request.h" | 25 #include "mojo/public/cpp/bindings/associated_interface_request.h" |
25 #include "mojo/public/cpp/bindings/binding.h" | 26 #include "mojo/public/cpp/bindings/binding.h" |
26 #include "mojo/public/cpp/bindings/lib/multiplex_router.h" | 27 #include "mojo/public/cpp/bindings/lib/multiplex_router.h" |
(...skipping 1023 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1050 // Block until the method callback is called on the background thread. | 1051 // Block until the method callback is called on the background thread. |
1051 run_loop.Run(); | 1052 run_loop.Run(); |
1052 } | 1053 } |
1053 | 1054 |
1054 struct ForwarderTestContext { | 1055 struct ForwarderTestContext { |
1055 IntegerSenderConnectionPtr connection_ptr; | 1056 IntegerSenderConnectionPtr connection_ptr; |
1056 std::unique_ptr<IntegerSenderConnectionImpl> interface_impl; | 1057 std::unique_ptr<IntegerSenderConnectionImpl> interface_impl; |
1057 }; | 1058 }; |
1058 | 1059 |
1059 TEST_F(AssociatedInterfaceTest, BindLaterThreadSafeAssociatedInterfacePtr) { | 1060 TEST_F(AssociatedInterfaceTest, BindLaterThreadSafeAssociatedInterfacePtr) { |
1060 // Create a ThreadSafeAssociatedPtr that we'll bind from a different thread. | |
1061 scoped_refptr<ThreadSafeIntegerSenderAssociatedPtr> thread_safe_ptr = | |
1062 ThreadSafeIntegerSenderAssociatedPtr::CreateUnbound(); | |
1063 | |
1064 // Start the thread from where we'll bind the interface pointer. | 1061 // Start the thread from where we'll bind the interface pointer. |
1065 base::Thread other_thread("service test thread"); | 1062 base::Thread other_thread("service test thread"); |
1066 other_thread.Start(); | 1063 other_thread.Start(); |
1067 const scoped_refptr<base::SingleThreadTaskRunner>& other_thread_task_runner = | 1064 const scoped_refptr<base::SingleThreadTaskRunner>& other_thread_task_runner = |
1068 other_thread.message_loop()->task_runner(); | 1065 other_thread.message_loop()->task_runner(); |
1069 ForwarderTestContext* context = new ForwarderTestContext(); | 1066 ForwarderTestContext* context = new ForwarderTestContext(); |
1070 { | |
1071 base::RunLoop run_loop; | |
1072 auto run_method = base::Bind( | |
1073 [](const scoped_refptr<base::TaskRunner>& main_task_runner, | |
1074 const base::Closure& quit_closure, | |
1075 const scoped_refptr<ThreadSafeIntegerSenderAssociatedPtr>& | |
1076 thread_safe_ptr, | |
1077 ForwarderTestContext* context) { | |
1078 // We are on the background thread, create the interface ptr. | |
1079 context->interface_impl = | |
1080 base::MakeUnique<IntegerSenderConnectionImpl>( | |
1081 MakeRequest(&(context->connection_ptr))); | |
1082 IntegerSenderAssociatedPtr sender; | |
1083 context->connection_ptr->GetSender( | |
1084 MakeRequest(&sender, context->connection_ptr.associated_group())); | |
1085 thread_safe_ptr->Bind(std::move(sender)); | |
1086 main_task_runner->PostTask(FROM_HERE, quit_closure); | |
1087 }, | |
1088 base::SequencedTaskRunnerHandle::Get(), run_loop.QuitClosure(), | |
1089 thread_safe_ptr, context); | |
1090 | 1067 |
1091 other_thread_task_runner->PostTask(FROM_HERE, run_method); | 1068 base::WaitableEvent echo_called_event( |
1092 // Block until the associated pointer is bound. | 1069 base::WaitableEvent::ResetPolicy::MANUAL, |
1093 run_loop.Run(); | 1070 base::WaitableEvent::InitialState::NOT_SIGNALED); |
1094 } | 1071 |
| 1072 // Create a ThreadSafeAssociatedPtr that we'll bind from a different thread. |
| 1073 scoped_refptr<ThreadSafeIntegerSenderAssociatedPtr> thread_safe_ptr = |
| 1074 ThreadSafeIntegerSenderAssociatedPtr::CreateUnbound( |
| 1075 other_thread_task_runner); |
| 1076 |
| 1077 base::RunLoop bind_run_loop; |
| 1078 auto run_method = base::Bind( |
| 1079 [](base::WaitableEvent* echo_called_event, |
| 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); |
1095 | 1099 |
1096 { | 1100 { |
1097 // Now we can call methods on the interface from the main thread. | 1101 // Now we can call methods on the interface from the main thread. |
1098 auto echo_callback = | 1102 auto echo_callback = |
1099 base::Bind([](const base::Closure& quit_closure, int32_t result) { | 1103 base::Bind([](const base::Closure& quit_closure, int32_t result) { |
1100 EXPECT_EQ(123, result); | 1104 EXPECT_EQ(123, result); |
1101 quit_closure.Run(); | 1105 quit_closure.Run(); |
1102 }); | 1106 }); |
1103 base::RunLoop run_loop; | 1107 base::RunLoop run_loop; |
1104 (*thread_safe_ptr) | 1108 (*thread_safe_ptr) |
1105 ->Echo(123, base::Bind(echo_callback, run_loop.QuitClosure())); | 1109 ->Echo(123, base::Bind(echo_callback, run_loop.QuitClosure())); |
| 1110 |
| 1111 // Let the bind happen on the background thread. |
| 1112 echo_called_event.Signal(); |
| 1113 |
1106 // Block until the method callback is called. | 1114 // Block until the method callback is called. |
1107 run_loop.Run(); | 1115 run_loop.Run(); |
1108 } | 1116 } |
1109 | 1117 |
1110 other_thread_task_runner->DeleteSoon(FROM_HERE, context); | 1118 other_thread_task_runner->DeleteSoon(FROM_HERE, context); |
1111 | 1119 |
1112 // Reset the pointer now so the InterfacePtr associated resources can be | 1120 // Reset the pointer now so the InterfacePtr associated resources can be |
1113 // deleted before the background thread's message loop is invalidated. | 1121 // deleted before the background thread's message loop is invalidated. |
1114 thread_safe_ptr = nullptr; | 1122 thread_safe_ptr = nullptr; |
1115 } | 1123 } |
1116 | 1124 |
1117 } // namespace | 1125 } // namespace |
1118 } // namespace test | 1126 } // namespace test |
1119 } // namespace mojo | 1127 } // namespace mojo |
OLD | NEW |