Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(210)

Side by Side Diff: ipc/ipc_sync_channel_unittest.cc

Issue 6810013: Add sync context dispatch restriction (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix flaky test Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ipc/ipc_sync_channel.cc ('k') | ipc/ipc_sync_message_unittest.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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 void OnDoPing(int ping) {
1180 // Send an asynchronous message that unblocks the caller.
1181 IPC::Message* msg = new SyncChannelTestMsg_Ping(ping);
1182 msg->set_unblock(true);
1183 Send(msg);
1184 // Signal the event after the message has been sent on the channel, on the
1185 // IPC thread.
1186 ipc_thread().message_loop()->PostTask(FROM_HERE,
1187 NewRunnableMethod(this, &RestrictedDispatchServer::OnPingSent));
1188 }
1189
1190 base::Thread* ListenerThread() { return Worker::ListenerThread(); }
1191
1192 private:
1193 bool OnMessageReceived(const Message& message) {
1194 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchServer, message)
1195 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs)
1196 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, Done)
1197 IPC_END_MESSAGE_MAP()
1198 return true;
1199 }
1200
1201 void OnPingSent() {
1202 sent_ping_event_->Signal();
1203 }
1204
1205 void OnNoArgs() { }
1206 WaitableEvent* sent_ping_event_;
1207 };
1208
1209 class NonRestrictedDispatchServer : public Worker {
1210 public:
1211 NonRestrictedDispatchServer()
1212 : Worker("non_restricted_channel", Channel::MODE_SERVER) {}
1213
1214 private:
1215 bool OnMessageReceived(const Message& message) {
1216 IPC_BEGIN_MESSAGE_MAP(NonRestrictedDispatchServer, message)
1217 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs)
1218 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, Done)
1219 IPC_END_MESSAGE_MAP()
1220 return true;
1221 }
1222
1223 void OnNoArgs() { }
1224 };
1225
1226 class RestrictedDispatchClient : public Worker {
1227 public:
1228 RestrictedDispatchClient(WaitableEvent* sent_ping_event,
1229 RestrictedDispatchServer* server,
1230 int* success)
1231 : Worker("restricted_channel", Channel::MODE_CLIENT),
1232 ping_(0),
1233 server_(server),
1234 success_(success),
1235 sent_ping_event_(sent_ping_event) {}
1236
1237 void Run() {
1238 // Incoming messages from our channel should only be dispatched when we
1239 // send a message on that same channel.
1240 channel()->SetRestrictDispatchToSameChannel(true);
1241
1242 server_->ListenerThread()->message_loop()->PostTask(FROM_HERE,
1243 NewRunnableMethod(server_, &RestrictedDispatchServer::OnDoPing, 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 server_->ListenerThread()->message_loop()->PostTask(FROM_HERE,
1256 NewRunnableMethod(server_, &RestrictedDispatchServer::OnDoPing, 2));
1257 sent_ping_event_->Wait();
1258 // Check that the incoming message is *not* dispatched when sending on the
1259 // non restricted channel.
1260 // TODO(piman): there is a possibility of a false positive race condition
1261 // here, if the message that was posted on the server-side end of the pipe
1262 // is not visible yet on the client side, but I don't know how to solve this
1263 // without hooking into the internals of SyncChannel. I haven't seen it in
1264 // practice (i.e. not setting SetRestrictDispatchToSameChannel does cause
1265 // the following to fail).
1266 non_restricted_channel->Send(new SyncChannelTestMsg_NoArgs);
1267 if (ping_ == 1)
1268 ++*success_;
1269 else
1270 LOG(ERROR) << "Send dispatched message from restricted channel";
1271
1272 Send(new SyncChannelTestMsg_NoArgs);
1273 if (ping_ == 2)
1274 ++*success_;
1275 else
1276 LOG(ERROR) << "Send failed to dispatch incoming message on same channel";
1277
1278 non_restricted_channel->Send(new SyncChannelTestMsg_Done);
1279 non_restricted_channel.reset();
1280 Send(new SyncChannelTestMsg_Done);
1281 Done();
1282 }
1283
1284 private:
1285 bool OnMessageReceived(const Message& message) {
1286 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchClient, message)
1287 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Ping, OnPing)
1288 IPC_END_MESSAGE_MAP()
1289 return true;
1290 }
1291
1292 void OnPing(int ping) {
1293 ping_ = ping;
1294 }
1295
1296 int ping_;
1297 RestrictedDispatchServer* server_;
1298 int* success_;
1299 WaitableEvent* sent_ping_event_;
1300 };
1301
1302 } // namespace
1303
1304 TEST_F(IPCSyncChannelTest, RestrictedDispatch) {
1305 WaitableEvent sent_ping_event(false, false);
1306
1307 RestrictedDispatchServer* server =
1308 new RestrictedDispatchServer(&sent_ping_event);
1309 int success = 0;
1310 std::vector<Worker*> workers;
1311 workers.push_back(new NonRestrictedDispatchServer);
1312 workers.push_back(server);
1313 workers.push_back(
1314 new RestrictedDispatchClient(&sent_ping_event, server, &success));
1315 RunTest(workers);
1316 EXPECT_EQ(3, success);
1317 }
OLDNEW
« no previous file with comments | « ipc/ipc_sync_channel.cc ('k') | ipc/ipc_sync_message_unittest.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698