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

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: Add 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 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 }
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