OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 // Unit test for SyncChannel. | 5 // Unit test for SyncChannel. |
6 | 6 |
7 #include "ipc/ipc_sync_channel.h" | 7 #include "ipc/ipc_sync_channel.h" |
8 | 8 |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
| 13 #include "base/bind.h" |
13 #include "base/logging.h" | 14 #include "base/logging.h" |
14 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
15 #include "base/message_loop.h" | 16 #include "base/message_loop.h" |
16 #include "base/stl_util.h" | 17 #include "base/stl_util.h" |
17 #include "base/string_util.h" | 18 #include "base/string_util.h" |
18 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" | 19 #include "base/third_party/dynamic_annotations/dynamic_annotations.h" |
19 #include "base/threading/platform_thread.h" | 20 #include "base/threading/platform_thread.h" |
20 #include "base/threading/thread.h" | 21 #include "base/threading/thread.h" |
21 #include "base/synchronization/waitable_event.h" | 22 #include "base/synchronization/waitable_event.h" |
22 #include "ipc/ipc_message.h" | 23 #include "ipc/ipc_message.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 // to suppress using standard Valgrind mechanism (suppressions). | 64 // to suppress using standard Valgrind mechanism (suppressions). |
64 // We have to use ANNOTATE_BENIGN_RACE to hide the reports and | 65 // We have to use ANNOTATE_BENIGN_RACE to hide the reports and |
65 // make ThreadSanitizer bots green. | 66 // make ThreadSanitizer bots green. |
66 ANNOTATE_BENIGN_RACE(this, "Race on vfptr, http://crbug.com/25841"); | 67 ANNOTATE_BENIGN_RACE(this, "Race on vfptr, http://crbug.com/25841"); |
67 } | 68 } |
68 | 69 |
69 // The IPC thread needs to outlive SyncChannel, so force the correct order of | 70 // The IPC thread needs to outlive SyncChannel, so force the correct order of |
70 // destruction. | 71 // destruction. |
71 virtual ~Worker() { | 72 virtual ~Worker() { |
72 WaitableEvent listener_done(false, false), ipc_done(false, false); | 73 WaitableEvent listener_done(false, false), ipc_done(false, false); |
73 ListenerThread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | 74 ListenerThread()->message_loop()->PostTask( |
74 this, &Worker::OnListenerThreadShutdown1, &listener_done, | 75 FROM_HERE, base::Bind(&Worker::OnListenerThreadShutdown1, this, |
75 &ipc_done)); | 76 &listener_done, &ipc_done)); |
76 listener_done.Wait(); | 77 listener_done.Wait(); |
77 ipc_done.Wait(); | 78 ipc_done.Wait(); |
78 ipc_thread_.Stop(); | 79 ipc_thread_.Stop(); |
79 listener_thread_.Stop(); | 80 listener_thread_.Stop(); |
80 } | 81 } |
81 void AddRef() { } | 82 void AddRef() { } |
82 void Release() { } | 83 void Release() { } |
83 static bool ImplementsThreadSafeReferenceCounting() { return true; } | 84 static bool ImplementsThreadSafeReferenceCounting() { return true; } |
84 bool Send(Message* msg) { return channel_->Send(msg); } | 85 bool Send(Message* msg) { return channel_->Send(msg); } |
85 bool SendWithTimeout(Message* msg, int timeout_ms) { | 86 bool SendWithTimeout(Message* msg, int timeout_ms) { |
86 return channel_->SendWithTimeout(msg, timeout_ms); | 87 return channel_->SendWithTimeout(msg, timeout_ms); |
87 } | 88 } |
88 void WaitForChannelCreation() { channel_created_->Wait(); } | 89 void WaitForChannelCreation() { channel_created_->Wait(); } |
89 void CloseChannel() { | 90 void CloseChannel() { |
90 DCHECK(MessageLoop::current() == ListenerThread()->message_loop()); | 91 DCHECK(MessageLoop::current() == ListenerThread()->message_loop()); |
91 channel_->Close(); | 92 channel_->Close(); |
92 } | 93 } |
93 void Start() { | 94 void Start() { |
94 StartThread(&listener_thread_, MessageLoop::TYPE_DEFAULT); | 95 StartThread(&listener_thread_, MessageLoop::TYPE_DEFAULT); |
95 ListenerThread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | 96 ListenerThread()->message_loop()->PostTask( |
96 this, &Worker::OnStart)); | 97 FROM_HERE, base::Bind(&Worker::OnStart, this)); |
97 } | 98 } |
98 void OverrideThread(base::Thread* overrided_thread) { | 99 void OverrideThread(base::Thread* overrided_thread) { |
99 DCHECK(overrided_thread_ == NULL); | 100 DCHECK(overrided_thread_ == NULL); |
100 overrided_thread_ = overrided_thread; | 101 overrided_thread_ = overrided_thread; |
101 } | 102 } |
102 bool SendAnswerToLife(bool pump, int timeout, bool succeed) { | 103 bool SendAnswerToLife(bool pump, int timeout, bool succeed) { |
103 int answer = 0; | 104 int answer = 0; |
104 SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer); | 105 SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer); |
105 if (pump) | 106 if (pump) |
106 msg->EnableMessagePumping(); | 107 msg->EnableMessagePumping(); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 Run(); | 174 Run(); |
174 } | 175 } |
175 | 176 |
176 void OnListenerThreadShutdown1(WaitableEvent* listener_event, | 177 void OnListenerThreadShutdown1(WaitableEvent* listener_event, |
177 WaitableEvent* ipc_event) { | 178 WaitableEvent* ipc_event) { |
178 // SyncChannel needs to be destructed on the thread that it was created on. | 179 // SyncChannel needs to be destructed on the thread that it was created on. |
179 channel_.reset(); | 180 channel_.reset(); |
180 | 181 |
181 MessageLoop::current()->RunAllPending(); | 182 MessageLoop::current()->RunAllPending(); |
182 | 183 |
183 ipc_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | 184 ipc_thread_.message_loop()->PostTask( |
184 this, &Worker::OnIPCThreadShutdown, listener_event, ipc_event)); | 185 FROM_HERE, base::Bind(&Worker::OnIPCThreadShutdown, this, |
| 186 listener_event, ipc_event)); |
185 } | 187 } |
186 | 188 |
187 void OnIPCThreadShutdown(WaitableEvent* listener_event, | 189 void OnIPCThreadShutdown(WaitableEvent* listener_event, |
188 WaitableEvent* ipc_event) { | 190 WaitableEvent* ipc_event) { |
189 MessageLoop::current()->RunAllPending(); | 191 MessageLoop::current()->RunAllPending(); |
190 ipc_event->Signal(); | 192 ipc_event->Signal(); |
191 | 193 |
192 listener_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | 194 listener_thread_.message_loop()->PostTask( |
193 this, &Worker::OnListenerThreadShutdown2, listener_event)); | 195 FROM_HERE, base::Bind(&Worker::OnListenerThreadShutdown2, this, |
| 196 listener_event)); |
194 } | 197 } |
195 | 198 |
196 void OnListenerThreadShutdown2(WaitableEvent* listener_event) { | 199 void OnListenerThreadShutdown2(WaitableEvent* listener_event) { |
197 MessageLoop::current()->RunAllPending(); | 200 MessageLoop::current()->RunAllPending(); |
198 listener_event->Signal(); | 201 listener_event->Signal(); |
199 } | 202 } |
200 | 203 |
201 bool OnMessageReceived(const Message& message) { | 204 bool OnMessageReceived(const Message& message) { |
202 IPC_BEGIN_MESSAGE_MAP(Worker, message) | 205 IPC_BEGIN_MESSAGE_MAP(Worker, message) |
203 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_Double, OnDoubleDelay) | 206 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_Double, OnDoubleDelay) |
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1017 : SyncMessageFilter(shutdown_event), | 1020 : SyncMessageFilter(shutdown_event), |
1018 worker_(worker), | 1021 worker_(worker), |
1019 thread_("helper_thread") { | 1022 thread_("helper_thread") { |
1020 base::Thread::Options options; | 1023 base::Thread::Options options; |
1021 options.message_loop_type = MessageLoop::TYPE_DEFAULT; | 1024 options.message_loop_type = MessageLoop::TYPE_DEFAULT; |
1022 thread_.StartWithOptions(options); | 1025 thread_.StartWithOptions(options); |
1023 } | 1026 } |
1024 | 1027 |
1025 virtual void OnFilterAdded(Channel* channel) { | 1028 virtual void OnFilterAdded(Channel* channel) { |
1026 SyncMessageFilter::OnFilterAdded(channel); | 1029 SyncMessageFilter::OnFilterAdded(channel); |
1027 thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | 1030 thread_.message_loop()->PostTask( |
1028 this, &TestSyncMessageFilter::SendMessageOnHelperThread)); | 1031 FROM_HERE, |
| 1032 base::Bind(&TestSyncMessageFilter::SendMessageOnHelperThread, this)); |
1029 } | 1033 } |
1030 | 1034 |
1031 void SendMessageOnHelperThread() { | 1035 void SendMessageOnHelperThread() { |
1032 int answer = 0; | 1036 int answer = 0; |
1033 bool result = Send(new SyncChannelTestMsg_AnswerToLife(&answer)); | 1037 bool result = Send(new SyncChannelTestMsg_AnswerToLife(&answer)); |
1034 DCHECK(result); | 1038 DCHECK(result); |
1035 DCHECK_EQ(answer, 42); | 1039 DCHECK_EQ(answer, 42); |
1036 | 1040 |
1037 worker_->Done(); | 1041 worker_->Done(); |
1038 } | 1042 } |
(...skipping 19 matching lines...) Expand all Loading... |
1058 // This class provides functionality to test the case that a Send on the sync | 1062 // This class provides functionality to test the case that a Send on the sync |
1059 // channel does not crash after the channel has been closed. | 1063 // channel does not crash after the channel has been closed. |
1060 class ServerSendAfterClose : public Worker { | 1064 class ServerSendAfterClose : public Worker { |
1061 public: | 1065 public: |
1062 ServerSendAfterClose() | 1066 ServerSendAfterClose() |
1063 : Worker(Channel::MODE_SERVER, "simpler_server"), | 1067 : Worker(Channel::MODE_SERVER, "simpler_server"), |
1064 send_result_(true) { | 1068 send_result_(true) { |
1065 } | 1069 } |
1066 | 1070 |
1067 bool SendDummy() { | 1071 bool SendDummy() { |
1068 ListenerThread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( | 1072 ListenerThread()->message_loop()->PostTask( |
1069 this, &ServerSendAfterClose::Send, new SyncChannelTestMsg_NoArgs)); | 1073 FROM_HERE, base::IgnoreReturn<bool>( |
| 1074 base::Bind(&ServerSendAfterClose::Send, this, |
| 1075 new SyncChannelTestMsg_NoArgs))); |
1070 return true; | 1076 return true; |
1071 } | 1077 } |
1072 | 1078 |
1073 bool send_result() const { | 1079 bool send_result() const { |
1074 return send_result_; | 1080 return send_result_; |
1075 } | 1081 } |
1076 | 1082 |
1077 private: | 1083 private: |
1078 virtual void Run() { | 1084 virtual void Run() { |
1079 CloseChannel(); | 1085 CloseChannel(); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1123 : Worker("restricted_channel", Channel::MODE_SERVER), | 1129 : Worker("restricted_channel", Channel::MODE_SERVER), |
1124 sent_ping_event_(sent_ping_event) { } | 1130 sent_ping_event_(sent_ping_event) { } |
1125 | 1131 |
1126 void OnDoPing(int ping) { | 1132 void OnDoPing(int ping) { |
1127 // Send an asynchronous message that unblocks the caller. | 1133 // Send an asynchronous message that unblocks the caller. |
1128 Message* msg = new SyncChannelTestMsg_Ping(ping); | 1134 Message* msg = new SyncChannelTestMsg_Ping(ping); |
1129 msg->set_unblock(true); | 1135 msg->set_unblock(true); |
1130 Send(msg); | 1136 Send(msg); |
1131 // Signal the event after the message has been sent on the channel, on the | 1137 // Signal the event after the message has been sent on the channel, on the |
1132 // IPC thread. | 1138 // IPC thread. |
1133 ipc_thread().message_loop()->PostTask(FROM_HERE, | 1139 ipc_thread().message_loop()->PostTask( |
1134 NewRunnableMethod(this, &RestrictedDispatchServer::OnPingSent)); | 1140 FROM_HERE, base::Bind(&RestrictedDispatchServer::OnPingSent, this)); |
1135 } | 1141 } |
1136 | 1142 |
1137 base::Thread* ListenerThread() { return Worker::ListenerThread(); } | 1143 base::Thread* ListenerThread() { return Worker::ListenerThread(); } |
1138 | 1144 |
1139 private: | 1145 private: |
1140 bool OnMessageReceived(const Message& message) { | 1146 bool OnMessageReceived(const Message& message) { |
1141 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchServer, message) | 1147 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchServer, message) |
1142 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs) | 1148 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs) |
1143 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, Done) | 1149 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, Done) |
1144 IPC_END_MESSAGE_MAP() | 1150 IPC_END_MESSAGE_MAP() |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1179 ping_(0), | 1185 ping_(0), |
1180 server_(server), | 1186 server_(server), |
1181 success_(success), | 1187 success_(success), |
1182 sent_ping_event_(sent_ping_event) {} | 1188 sent_ping_event_(sent_ping_event) {} |
1183 | 1189 |
1184 void Run() { | 1190 void Run() { |
1185 // Incoming messages from our channel should only be dispatched when we | 1191 // Incoming messages from our channel should only be dispatched when we |
1186 // send a message on that same channel. | 1192 // send a message on that same channel. |
1187 channel()->SetRestrictDispatchToSameChannel(true); | 1193 channel()->SetRestrictDispatchToSameChannel(true); |
1188 | 1194 |
1189 server_->ListenerThread()->message_loop()->PostTask(FROM_HERE, | 1195 server_->ListenerThread()->message_loop()->PostTask( |
1190 NewRunnableMethod(server_, &RestrictedDispatchServer::OnDoPing, 1)); | 1196 FROM_HERE, base::Bind(&RestrictedDispatchServer::OnDoPing, server_, 1)); |
1191 sent_ping_event_->Wait(); | 1197 sent_ping_event_->Wait(); |
1192 Send(new SyncChannelTestMsg_NoArgs); | 1198 Send(new SyncChannelTestMsg_NoArgs); |
1193 if (ping_ == 1) | 1199 if (ping_ == 1) |
1194 ++*success_; | 1200 ++*success_; |
1195 else | 1201 else |
1196 LOG(ERROR) << "Send failed to dispatch incoming message on same channel"; | 1202 LOG(ERROR) << "Send failed to dispatch incoming message on same channel"; |
1197 | 1203 |
1198 scoped_ptr<SyncChannel> non_restricted_channel(new SyncChannel( | 1204 scoped_ptr<SyncChannel> non_restricted_channel(new SyncChannel( |
1199 "non_restricted_channel", Channel::MODE_CLIENT, this, | 1205 "non_restricted_channel", Channel::MODE_CLIENT, this, |
1200 ipc_thread().message_loop_proxy(), true, shutdown_event())); | 1206 ipc_thread().message_loop_proxy(), true, shutdown_event())); |
1201 | 1207 |
1202 server_->ListenerThread()->message_loop()->PostTask(FROM_HERE, | 1208 server_->ListenerThread()->message_loop()->PostTask( |
1203 NewRunnableMethod(server_, &RestrictedDispatchServer::OnDoPing, 2)); | 1209 FROM_HERE, base::Bind(&RestrictedDispatchServer::OnDoPing, server_, 2)); |
1204 sent_ping_event_->Wait(); | 1210 sent_ping_event_->Wait(); |
1205 // Check that the incoming message is *not* dispatched when sending on the | 1211 // Check that the incoming message is *not* dispatched when sending on the |
1206 // non restricted channel. | 1212 // non restricted channel. |
1207 // TODO(piman): there is a possibility of a false positive race condition | 1213 // TODO(piman): there is a possibility of a false positive race condition |
1208 // here, if the message that was posted on the server-side end of the pipe | 1214 // here, if the message that was posted on the server-side end of the pipe |
1209 // is not visible yet on the client side, but I don't know how to solve this | 1215 // is not visible yet on the client side, but I don't know how to solve this |
1210 // without hooking into the internals of SyncChannel. I haven't seen it in | 1216 // without hooking into the internals of SyncChannel. I haven't seen it in |
1211 // practice (i.e. not setting SetRestrictDispatchToSameChannel does cause | 1217 // practice (i.e. not setting SetRestrictDispatchToSameChannel does cause |
1212 // the following to fail). | 1218 // the following to fail). |
1213 non_restricted_channel->Send(new SyncChannelTestMsg_NoArgs); | 1219 non_restricted_channel->Send(new SyncChannelTestMsg_NoArgs); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1257 std::vector<Worker*> workers; | 1263 std::vector<Worker*> workers; |
1258 workers.push_back(new NonRestrictedDispatchServer); | 1264 workers.push_back(new NonRestrictedDispatchServer); |
1259 workers.push_back(server); | 1265 workers.push_back(server); |
1260 workers.push_back( | 1266 workers.push_back( |
1261 new RestrictedDispatchClient(&sent_ping_event, server, &success)); | 1267 new RestrictedDispatchClient(&sent_ping_event, server, &success)); |
1262 RunTest(workers); | 1268 RunTest(workers); |
1263 EXPECT_EQ(3, success); | 1269 EXPECT_EQ(3, success); |
1264 } | 1270 } |
1265 | 1271 |
1266 } // namespace IPC | 1272 } // namespace IPC |
OLD | NEW |