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> |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
151 } | 151 } |
152 | 152 |
153 virtual void OnNestedTestMsg(Message* reply_msg) { | 153 virtual void OnNestedTestMsg(Message* reply_msg) { |
154 NOTREACHED(); | 154 NOTREACHED(); |
155 } | 155 } |
156 | 156 |
157 base::Thread* ListenerThread() { | 157 base::Thread* ListenerThread() { |
158 return overrided_thread_ ? overrided_thread_ : &listener_thread_; | 158 return overrided_thread_ ? overrided_thread_ : &listener_thread_; |
159 } | 159 } |
160 | 160 |
161 const base::Thread& ipc_thread() const { return ipc_thread_; } | |
162 | |
161 private: | 163 private: |
162 // Called on the listener thread to create the sync channel. | 164 // Called on the listener thread to create the sync channel. |
163 void OnStart() { | 165 void OnStart() { |
164 // Link ipc_thread_, listener_thread_ and channel_ altogether. | 166 // Link ipc_thread_, listener_thread_ and channel_ altogether. |
165 StartThread(&ipc_thread_, MessageLoop::TYPE_IO); | 167 StartThread(&ipc_thread_, MessageLoop::TYPE_IO); |
166 channel_.reset(new SyncChannel( | 168 channel_.reset(new SyncChannel( |
167 channel_name_, mode_, this, ipc_thread_.message_loop(), true, | 169 channel_name_, mode_, this, ipc_thread_.message_loop(), true, |
168 &shutdown_event_)); | 170 &shutdown_event_)); |
169 channel_created_->Signal(); | 171 channel_created_->Signal(); |
170 Run(); | 172 Run(); |
(...skipping 986 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1157 | 1159 |
1158 server.done_event()->Wait(); | 1160 server.done_event()->Wait(); |
1159 server.done_event()->Reset(); | 1161 server.done_event()->Reset(); |
1160 | 1162 |
1161 server.SendDummy(); | 1163 server.SendDummy(); |
1162 server.done_event()->Wait(); | 1164 server.done_event()->Wait(); |
1163 | 1165 |
1164 EXPECT_FALSE(server.send_result()); | 1166 EXPECT_FALSE(server.send_result()); |
1165 } | 1167 } |
1166 | 1168 |
1169 //----------------------------------------------------------------------------- | |
1167 | 1170 |
1171 namespace { | |
1172 | |
1173 class RestrictedDispatchServer : public Worker { | |
1174 public: | |
1175 RestrictedDispatchServer(WaitableEvent* sent_ping_event) | |
1176 : Worker("restricted_channel", Channel::MODE_SERVER), | |
1177 sent_ping_event_(sent_ping_event) { } | |
1178 | |
1179 private: | |
1180 bool OnMessageReceived(const Message& message) { | |
1181 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchServer, message) | |
1182 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_PostPing, OnPostPing) | |
1183 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs) | |
1184 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, Done) | |
1185 IPC_END_MESSAGE_MAP() | |
1186 return true; | |
1187 } | |
1188 | |
1189 void OnPostPing(int ping) { | |
1190 MessageLoop::current()->PostTask(FROM_HERE, | |
1191 NewRunnableMethod(this, &RestrictedDispatchServer::OnDoPing, ping)); | |
1192 } | |
1193 | |
1194 void OnDoPing(int ping) { | |
1195 // Send an asynchronous message that unblocks the caller. | |
1196 IPC::Message* msg = new SyncChannelTestMsg_Ping(ping); | |
1197 msg->set_unblock(true); | |
1198 Send(msg); | |
1199 // Signal the event after the message has been sent on the channel, on the | |
1200 // IPC thread. | |
1201 ipc_thread().message_loop()->PostTask(FROM_HERE, | |
1202 NewRunnableMethod(this, &RestrictedDispatchServer::OnPingSent)); | |
1203 } | |
1204 | |
1205 void OnPingSent() { | |
1206 sent_ping_event_->Signal(); | |
1207 } | |
1208 | |
1209 void OnNoArgs() { } | |
1210 WaitableEvent* sent_ping_event_; | |
1211 }; | |
1212 | |
1213 class NonRestrictedDispatchServer : public Worker { | |
1214 public: | |
1215 NonRestrictedDispatchServer() | |
1216 : Worker("non_restricted_channel", Channel::MODE_SERVER) {} | |
1217 | |
1218 private: | |
1219 bool OnMessageReceived(const Message& message) { | |
1220 IPC_BEGIN_MESSAGE_MAP(NonRestrictedDispatchServer, message) | |
1221 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs) | |
1222 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, Done) | |
1223 IPC_END_MESSAGE_MAP() | |
1224 return true; | |
1225 } | |
1226 | |
1227 void OnNoArgs() { } | |
1228 }; | |
1229 | |
1230 class RestrictedDispatchClient : public Worker { | |
1231 public: | |
1232 RestrictedDispatchClient(WaitableEvent* sent_ping_event, int* success) | |
1233 : Worker("restricted_channel", Channel::MODE_CLIENT), | |
1234 ping_(0), | |
1235 success_(success), | |
1236 sent_ping_event_(sent_ping_event) {} | |
1237 | |
1238 void Run() { | |
1239 // Incoming messages from our channel should only be dispatched when we | |
1240 // send a message on that same channel. | |
1241 channel()->SetRestrictDispatchToSameChannel(true); | |
1242 | |
1243 Send(new SyncChannelTestMsg_PostPing(1)); | |
1244 sent_ping_event_->Wait(); | |
1245 Send(new SyncChannelTestMsg_NoArgs); | |
1246 if (ping_ == 1) | |
1247 ++*success_; | |
1248 else | |
1249 LOG(ERROR) << "Send failed to dispatch incoming message on same channel"; | |
1250 | |
1251 scoped_ptr<SyncChannel> non_restricted_channel(new SyncChannel( | |
1252 "non_restricted_channel", Channel::MODE_CLIENT, this, | |
1253 ipc_thread().message_loop(), true, shutdown_event())); | |
1254 | |
1255 Send(new SyncChannelTestMsg_PostPing(2)); | |
piman
2011/04/08 02:07:03
This is flaky... even though I post a task on the
| |
1256 sent_ping_event_->Wait(); | |
1257 // Check that the incoming message is *not* dispatched when sending on the | |
1258 // non restricted channel. | |
1259 // TODO(piman): there is a possibility of a false positive race condition | |
1260 // here, if the message that was posted on the server-side end of the pipe | |
1261 // is not visible yet on the client side, but I don't know how to solve this | |
1262 // without hooking into the internals of SyncChannel. I haven't seen it in | |
1263 // practice (i.e. not setting SetRestrictDispatchToSameChannel does cause | |
1264 // the following to fail). | |
1265 non_restricted_channel->Send(new SyncChannelTestMsg_NoArgs); | |
1266 if (ping_ == 1) | |
1267 ++*success_; | |
1268 else | |
1269 LOG(ERROR) << "Send dispatched message from restricted channel"; | |
1270 | |
1271 Send(new SyncChannelTestMsg_NoArgs); | |
1272 if (ping_ == 2) | |
1273 ++*success_; | |
1274 else | |
1275 LOG(ERROR) << "Send failed to dispatch incoming message on same channel"; | |
1276 | |
1277 non_restricted_channel->Send(new SyncChannelTestMsg_Done); | |
1278 non_restricted_channel.reset(); | |
1279 Send(new SyncChannelTestMsg_Done); | |
1280 Done(); | |
1281 } | |
1282 | |
1283 private: | |
1284 bool OnMessageReceived(const Message& message) { | |
1285 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchClient, message) | |
1286 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Ping, OnPing) | |
1287 IPC_END_MESSAGE_MAP() | |
1288 return true; | |
1289 } | |
1290 | |
1291 void OnPing(int ping) { | |
1292 ping_ = ping; | |
1293 } | |
1294 | |
1295 int ping_; | |
1296 int* success_; | |
1297 WaitableEvent* sent_ping_event_; | |
1298 }; | |
1299 | |
1300 } // namespace | |
1301 | |
1302 TEST_F(IPCSyncChannelTest, RestrictedDispatch) { | |
1303 WaitableEvent sent_ping_event(false, false); | |
1304 | |
1305 int success = 0; | |
1306 std::vector<Worker*> workers; | |
1307 workers.push_back(new NonRestrictedDispatchServer); | |
1308 workers.push_back(new RestrictedDispatchServer(&sent_ping_event)); | |
1309 workers.push_back(new RestrictedDispatchClient(&sent_ping_event, &success)); | |
1310 RunTest(workers); | |
1311 EXPECT_EQ(3, success); | |
1312 } | |
OLD | NEW |