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

Side by Side Diff: chrome/common/ipc_sync_channel_unittest.cc

Issue 8001: Make IPC::SyncChannel not duplicate the underlying MessageLoop implementation... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 12 years, 1 month 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 | « chrome/common/ipc_sync_channel.cc ('k') | chrome/common/ipc_sync_message.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) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 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 <windows.h> 7 #include <windows.h>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 Worker(const std::wstring& channel_name, Channel::Mode mode) 76 Worker(const std::wstring& channel_name, Channel::Mode mode)
77 : channel_name_(channel_name), 77 : channel_name_(channel_name),
78 mode_(mode), 78 mode_(mode),
79 ipc_thread_((WideToUTF8(channel_name) + "_ipc").c_str()), 79 ipc_thread_((WideToUTF8(channel_name) + "_ipc").c_str()),
80 listener_thread_((WideToUTF8(channel_name) + "_listener").c_str()), 80 listener_thread_((WideToUTF8(channel_name) + "_listener").c_str()),
81 overrided_thread_(NULL) { } 81 overrided_thread_(NULL) { }
82 82
83 // The IPC thread needs to outlive SyncChannel, so force the correct order of 83 // The IPC thread needs to outlive SyncChannel, so force the correct order of
84 // destruction. 84 // destruction.
85 virtual ~Worker() { 85 virtual ~Worker() {
86 CloseChannel(); 86 Event listener_done, ipc_done;
87 // We must stop the threads and release the channel here. The IPC thread 87 ListenerThread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
88 // must die before the listener thread, otherwise if its in the process of 88 this, &Worker::OnListenerThreadShutdown, listener_done.handle(),
89 // sending a message, it will get an error, it will use channel_, which 89 ipc_done.handle()));
90 // references listener_. There are many ways of crashing, depending on 90 HANDLE handles[] = { listener_done.handle(), ipc_done.handle() };
91 // timing. 91 WaitForMultipleObjects(2, handles, TRUE, INFINITE);
92 // This is a race condition so you may not see it all the time even if you
93 // reverse the Stop() calls. You may see this bug with AppVerifier only.
94 ipc_thread_.Stop(); 92 ipc_thread_.Stop();
95 listener_thread_.Stop(); 93 listener_thread_.Stop();
96 channel_.reset();
97 } 94 }
98 void AddRef() { } 95 void AddRef() { }
99 void Release() { } 96 void Release() { }
100 bool Send(Message* msg) { return channel_->Send(msg); } 97 bool Send(Message* msg) { return channel_->Send(msg); }
101 bool SendWithTimeout(Message* msg, int timeout_ms) { 98 bool SendWithTimeout(Message* msg, int timeout_ms) {
102 return channel_->SendWithTimeout(msg, timeout_ms); 99 return channel_->SendWithTimeout(msg, timeout_ms);
103 } 100 }
104 void WaitForChannelCreation() { channel_created_.Wait(); } 101 void WaitForChannelCreation() { channel_created_.Wait(); }
105 void CloseChannel() { channel_.reset(); } 102 void CloseChannel() {
103 DCHECK(MessageLoop::current() == ListenerThread()->message_loop());
104 channel_->Close();
105 }
106 void Start() { 106 void Start() {
107 StartThread(&listener_thread_); 107 StartThread(&listener_thread_);
108 base::Thread* thread = 108 ListenerThread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
109 overrided_thread_ ? overrided_thread_ : &listener_thread_;
110 thread->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
111 this, &Worker::OnStart)); 109 this, &Worker::OnStart));
112 } 110 }
113 void OverrideThread(base::Thread* overrided_thread) { 111 void OverrideThread(base::Thread* overrided_thread) {
114 DCHECK(overrided_thread_ == NULL); 112 DCHECK(overrided_thread_ == NULL);
115 overrided_thread_ = overrided_thread; 113 overrided_thread_ = overrided_thread;
116 } 114 }
117 Channel::Mode mode() { return mode_; } 115 Channel::Mode mode() { return mode_; }
118 HANDLE done_event() { return done_.handle(); } 116 HANDLE done_event() { return done_.handle(); }
119 117
120 protected: 118 protected:
121 // Derived classes need to call this when they've completed their part of 119 // Derived classes need to call this when they've completed their part of
122 // the test. 120 // the test.
123 void Done() { done_.Set(); } 121 void Done() { done_.Set(); }
124 122
125 // Functions for dervied classes to implement if they wish. 123 // Functions for dervied classes to implement if they wish.
126 virtual void Run() { } 124 virtual void Run() { }
127 virtual void OnDouble(int in, int* out) { NOTREACHED(); }
128 virtual void OnAnswer(int* answer) { NOTREACHED(); } 125 virtual void OnAnswer(int* answer) { NOTREACHED(); }
129 virtual void OnAnswerDelay(Message* reply_msg) { 126 virtual void OnAnswerDelay(Message* reply_msg) {
130 // The message handler map below can only take one entry for 127 // The message handler map below can only take one entry for
131 // SyncChannelTestMsg_AnswerToLife, so since some classes want 128 // SyncChannelTestMsg_AnswerToLife, so since some classes want
132 // the normal version while other want the delayed reply, we 129 // the normal version while other want the delayed reply, we
133 // call the normal version if the derived class didn't override 130 // call the normal version if the derived class didn't override
134 // this function. 131 // this function.
135 int answer; 132 int answer;
136 OnAnswer(&answer); 133 OnAnswer(&answer);
137 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, answer); 134 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, answer);
138 Send(reply_msg); 135 Send(reply_msg);
139 } 136 }
137 virtual void OnDouble(int in, int* out) { NOTREACHED(); }
138 virtual void OnDoubleDelay(int in, Message* reply_msg) {
139 int result;
140 OnDouble(in, &result);
141 SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, result);
142 Send(reply_msg);
143 }
140 144
141 private: 145 private:
146 base::Thread* ListenerThread() {
147 return overrided_thread_ ? overrided_thread_ : &listener_thread_;
148 }
142 // Called on the listener thread to create the sync channel. 149 // Called on the listener thread to create the sync channel.
143 void OnStart() { 150 void OnStart() {
144 // Link ipc_thread_, listener_thread_ and channel_ altogether. 151 // Link ipc_thread_, listener_thread_ and channel_ altogether.
145 StartThread(&ipc_thread_); 152 StartThread(&ipc_thread_);
146 channel_.reset(new SyncChannel( 153 channel_.reset(new SyncChannel(
147 channel_name_, mode_, this, NULL, ipc_thread_.message_loop(), true, 154 channel_name_, mode_, this, NULL, ipc_thread_.message_loop(), true,
148 TestProcess::GetShutDownEvent())); 155 TestProcess::GetShutDownEvent()));
149 channel_created_.Set(); 156 channel_created_.Set();
150 Run(); 157 Run();
151 } 158 }
152 159
160 void OnListenerThreadShutdown(HANDLE listener_event, HANDLE ipc_event) {
161 // SyncChannel needs to be destructed on the thread that it was created on.
162 channel_.reset();
163 SetEvent(listener_event);
164
165 ipc_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
166 this, &Worker::OnIPCThreadShutdown, ipc_event));
167 }
168
169 void OnIPCThreadShutdown(HANDLE ipc_event) {
170 SetEvent(ipc_event);
171 }
172
153 void OnMessageReceived(const Message& message) { 173 void OnMessageReceived(const Message& message) {
154 IPC_BEGIN_MESSAGE_MAP(Worker, message) 174 IPC_BEGIN_MESSAGE_MAP(Worker, message)
155 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Double, OnDouble) 175 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_Double, OnDoubleDelay)
156 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_AnswerToLife, 176 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_AnswerToLife,
157 OnAnswerDelay) 177 OnAnswerDelay)
158 IPC_END_MESSAGE_MAP() 178 IPC_END_MESSAGE_MAP()
159 } 179 }
160 180
161 void StartThread(base::Thread* thread) { 181 void StartThread(base::Thread* thread) {
162 base::Thread::Options options; 182 base::Thread::Options options;
163 options.message_loop_type = MessageLoop::TYPE_IO; 183 options.message_loop_type = MessageLoop::TYPE_IO;
164 thread->StartWithOptions(options); 184 thread->StartWithOptions(options);
165 } 185 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 224
205 int count = static_cast<int>(done_handles.size()); 225 int count = static_cast<int>(done_handles.size());
206 WaitForMultipleObjects(count, &done_handles.front(), TRUE, INFINITE); 226 WaitForMultipleObjects(count, &done_handles.front(), TRUE, INFINITE);
207 STLDeleteContainerPointers(workers.begin(), workers.end()); 227 STLDeleteContainerPointers(workers.begin(), workers.end());
208 228
209 TestProcess::GlobalCleanup(); 229 TestProcess::GlobalCleanup();
210 } 230 }
211 231
212 } // namespace 232 } // namespace
213 233
214
215 //----------------------------------------------------------------------------- 234 //-----------------------------------------------------------------------------
216 235
217 namespace { 236 namespace {
218 237
219 class SimpleServer : public Worker { 238 class SimpleServer : public Worker {
220 public: 239 public:
221 SimpleServer() : Worker(Channel::MODE_SERVER, "simpler_server") { } 240 SimpleServer(bool pump_during_send)
241 : Worker(Channel::MODE_SERVER, "simpler_server"),
242 pump_during_send_(pump_during_send) { }
222 void Run() { 243 void Run() {
223 int answer = 0; 244 int answer = 0;
224 bool result = Send(new SyncChannelTestMsg_AnswerToLife(&answer)); 245 IPC::SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer);
246 if (pump_during_send_)
247 msg->EnableMessagePumping();
248 bool result = Send(msg);
225 DCHECK(result); 249 DCHECK(result);
226 DCHECK(answer == 42); 250 DCHECK(answer == 42);
227 Done(); 251 Done();
228 } 252 }
253
254 bool pump_during_send_;
229 }; 255 };
230 256
231 class SimpleClient : public Worker { 257 class SimpleClient : public Worker {
232 public: 258 public:
233 SimpleClient() : Worker(Channel::MODE_CLIENT, "simple_client") { } 259 SimpleClient() : Worker(Channel::MODE_CLIENT, "simple_client") { }
234 260
235 void OnAnswer(int* answer) { 261 void OnAnswer(int* answer) {
236 *answer = 42; 262 *answer = 42;
237 Done(); 263 Done();
238 } 264 }
239 }; 265 };
240 266
267 void Simple(bool pump_during_send) {
268 std::vector<Worker*> workers;
269 workers.push_back(new SimpleServer(pump_during_send));
270 workers.push_back(new SimpleClient());
271 RunTest(workers);
272 }
273
241 } // namespace 274 } // namespace
242 275
243 // Tests basic synchronous call 276 // Tests basic synchronous call
244 TEST_F(IPCSyncChannelTest, Simple) { 277 TEST_F(IPCSyncChannelTest, Simple) {
245 std::vector<Worker*> workers; 278 Simple(false);
246 workers.push_back(new SimpleServer()); 279 Simple(true);
247 workers.push_back(new SimpleClient());
248 RunTest(workers);
249 } 280 }
250 281
251
252 //----------------------------------------------------------------------------- 282 //-----------------------------------------------------------------------------
253 283
254 namespace { 284 namespace {
255 285
256 class DelayClient : public Worker { 286 class DelayClient : public Worker {
257 public: 287 public:
258 DelayClient() : Worker(Channel::MODE_CLIENT, "delay_client") { } 288 DelayClient() : Worker(Channel::MODE_CLIENT, "delay_client") { }
259 289
260 void OnAnswerDelay(Message* reply_msg) { 290 void OnAnswerDelay(Message* reply_msg) {
261 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42); 291 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42);
262 Send(reply_msg); 292 Send(reply_msg);
263 Done(); 293 Done();
264 } 294 }
265 }; 295 };
266 296
297 void DelayReply(bool pump_during_send) {
298 std::vector<Worker*> workers;
299 workers.push_back(new SimpleServer(pump_during_send));
300 workers.push_back(new DelayClient());
301 RunTest(workers);
302 }
303
267 } // namespace 304 } // namespace
268 305
269 // Tests that asynchronous replies work 306 // Tests that asynchronous replies work
270 TEST_F(IPCSyncChannelTest, DelayReply) { 307 TEST_F(IPCSyncChannelTest, DelayReply) {
271 std::vector<Worker*> workers; 308 DelayReply(false);
272 workers.push_back(new SimpleServer()); 309 DelayReply(true);
273 workers.push_back(new DelayClient());
274 RunTest(workers);
275 } 310 }
276 311
277
278 //----------------------------------------------------------------------------- 312 //-----------------------------------------------------------------------------
279 313
280 namespace { 314 namespace {
281 315
282 class NoHangServer : public Worker { 316 class NoHangServer : public Worker {
283 public: 317 public:
284 explicit NoHangServer(Event* got_first_reply) 318 explicit NoHangServer(Event* got_first_reply, bool pump_during_send)
285 : Worker(Channel::MODE_SERVER, "no_hang_server"), 319 : Worker(Channel::MODE_SERVER, "no_hang_server"),
286 got_first_reply_(got_first_reply) { } 320 got_first_reply_(got_first_reply),
321 pump_during_send_(pump_during_send) { }
287 void Run() { 322 void Run() {
288 int answer = 0; 323 int answer = 0;
289 bool result = Send(new SyncChannelTestMsg_AnswerToLife(&answer)); 324 IPC::SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer);
325 if (pump_during_send_)
326 msg->EnableMessagePumping();
327 bool result = Send(msg);
290 DCHECK(result); 328 DCHECK(result);
291 DCHECK(answer == 42); 329 DCHECK(answer == 42);
292 got_first_reply_->Set(); 330 got_first_reply_->Set();
293 331
294 result = Send(new SyncChannelTestMsg_AnswerToLife(&answer)); 332 msg = new SyncChannelTestMsg_AnswerToLife(&answer);
333 if (pump_during_send_)
334 msg->EnableMessagePumping();
335 result = Send(msg);
295 DCHECK(!result); 336 DCHECK(!result);
296 Done(); 337 Done();
297 } 338 }
298 339
299 Event* got_first_reply_; 340 Event* got_first_reply_;
341 bool pump_during_send_;
300 }; 342 };
301 343
302 class NoHangClient : public Worker { 344 class NoHangClient : public Worker {
303 public: 345 public:
304 explicit NoHangClient(Event* got_first_reply) 346 explicit NoHangClient(Event* got_first_reply)
305 : Worker(Channel::MODE_CLIENT, "no_hang_client"), 347 : Worker(Channel::MODE_CLIENT, "no_hang_client"),
306 got_first_reply_(got_first_reply) { } 348 got_first_reply_(got_first_reply) { }
307 349
308 virtual void OnAnswerDelay(Message* reply_msg) { 350 virtual void OnAnswerDelay(Message* reply_msg) {
309 // Use the DELAY_REPLY macro so that we can force the reply to be sent 351 // Use the DELAY_REPLY macro so that we can force the reply to be sent
310 // before this function returns (when the channel will be reset). 352 // before this function returns (when the channel will be reset).
311 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42); 353 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42);
312 Send(reply_msg); 354 Send(reply_msg);
313 got_first_reply_->Wait(); 355 got_first_reply_->Wait();
314 CloseChannel(); 356 CloseChannel();
315 Done(); 357 Done();
316 } 358 }
317 359
318 Event* got_first_reply_; 360 Event* got_first_reply_;
319 }; 361 };
320 362
363 void NoHang(bool pump_during_send) {
364 Event got_first_reply;
365 std::vector<Worker*> workers;
366 workers.push_back(new NoHangServer(&got_first_reply, pump_during_send));
367 workers.push_back(new NoHangClient(&got_first_reply));
368 RunTest(workers);
369 }
370
321 } // namespace 371 } // namespace
322 372
323 // Tests that caller doesn't hang if receiver dies 373 // Tests that caller doesn't hang if receiver dies
324 TEST_F(IPCSyncChannelTest, NoHang) { 374 TEST_F(IPCSyncChannelTest, NoHang) {
325 Event got_first_reply; 375 NoHang(false);
326 376 NoHang(true);
327 std::vector<Worker*> workers;
328 workers.push_back(new NoHangServer(&got_first_reply));
329 workers.push_back(new NoHangClient(&got_first_reply));
330 RunTest(workers);
331 } 377 }
332 378
333
334 //----------------------------------------------------------------------------- 379 //-----------------------------------------------------------------------------
335 380
336 namespace { 381 namespace {
337 382
338 class RecursiveServer : public Worker { 383 class UnblockServer : public Worker {
339 public: 384 public:
340 RecursiveServer() : Worker(Channel::MODE_SERVER, "recursive_server") { } 385 UnblockServer(bool pump_during_send)
386 : Worker(Channel::MODE_SERVER, "unblock_server"),
387 pump_during_send_(pump_during_send) { }
341 void Run() { 388 void Run() {
342 int answer = 0; 389 int answer = 0;
343 bool result = Send(new SyncChannelTestMsg_AnswerToLife(&answer)); 390 IPC::SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer);
391 if (pump_during_send_)
392 msg->EnableMessagePumping();
393 bool result = Send(msg);
344 DCHECK(result); 394 DCHECK(result);
345 DCHECK(answer == 42); 395 DCHECK(answer == 42);
346 Done(); 396 Done();
347 } 397 }
348 398
349 void OnDouble(int in, int* out) { 399 void OnDouble(int in, int* out) {
350 *out = in * 2; 400 *out = in * 2;
351 } 401 }
402
403 bool pump_during_send_;
404 };
405
406 class UnblockClient : public Worker {
407 public:
408 UnblockClient(bool pump_during_send)
409 : Worker(Channel::MODE_CLIENT, "unblock_client"),
410 pump_during_send_(pump_during_send) { }
411
412 void OnAnswer(int* answer) {
413 IPC::SyncMessage* msg = new SyncChannelTestMsg_Double(21, answer);
414 if (pump_during_send_)
415 msg->EnableMessagePumping();
416 BOOL result = Send(msg);
417 DCHECK(result);
418 Done();
419 }
420
421 bool pump_during_send_;
422 };
423
424 void Unblock(bool server_pump, bool client_pump) {
425 std::vector<Worker*> workers;
426 workers.push_back(new UnblockServer(server_pump));
427 workers.push_back(new UnblockClient(client_pump));
428 RunTest(workers);
429 }
430
431 } // namespace
432
433 // Tests that the caller unblocks to answer a sync message from the receiver.
434 TEST_F(IPCSyncChannelTest, Unblock) {
435 Unblock(false, false);
436 Unblock(false, true);
437 Unblock(true, false);
438 Unblock(true, true);
439 }
440
441 //-----------------------------------------------------------------------------
442
443 namespace {
444
445 class RecursiveServer : public Worker {
446 public:
447 explicit RecursiveServer(
448 bool expected_send_result, bool pump_first, bool pump_second)
449 : Worker(Channel::MODE_SERVER, "recursive_server"),
450 expected_send_result_(expected_send_result),
451 pump_first_(pump_first), pump_second_(pump_second) { }
452 void Run() {
453 int answer;
454 IPC::SyncMessage* msg = new SyncChannelTestMsg_Double(21, &answer);
455 if (pump_first_)
456 msg->EnableMessagePumping();
457 bool result = Send(msg);
458 DCHECK(result == expected_send_result_);
459 Done();
460 }
461
462 void OnDouble(int in, int* out) {
463 int answer;
464 IPC::SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer);
465 if (pump_second_)
466 msg->EnableMessagePumping();
467 bool result = Send(msg);
468 DCHECK(result == expected_send_result_);
469 }
470
471 bool expected_send_result_, pump_first_, pump_second_;
352 }; 472 };
353 473
354 class RecursiveClient : public Worker { 474 class RecursiveClient : public Worker {
355 public: 475 public:
356 RecursiveClient() : Worker(Channel::MODE_CLIENT, "recursive_client") { } 476 explicit RecursiveClient(bool pump_during_send, bool close_channel)
477 : Worker(Channel::MODE_CLIENT, "recursive_client"),
478 pump_during_send_(pump_during_send), close_channel_(close_channel) { }
357 479
358 void OnAnswer(int* answer) { 480 void OnDoubleDelay(int in, Message* reply_msg) {
359 BOOL result = Send(new SyncChannelTestMsg_Double(21, answer)); 481 int answer = 0;
360 DCHECK(result); 482 IPC::SyncMessage* msg = new SyncChannelTestMsg_Double(5, &answer);
483 if (pump_during_send_)
484 msg->EnableMessagePumping();
485 bool result = Send(msg);
486 DCHECK(result != close_channel_);
487 if (!close_channel_) {
488 SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, in * 2);
489 Send(reply_msg);
490 }
361 Done(); 491 Done();
362 } 492 }
493
494 void OnAnswerDelay(Message* reply_msg) {
495 if (close_channel_) {
496 CloseChannel();
497 } else {
498 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42);
499 Send(reply_msg);
500 }
501 }
502
503 bool pump_during_send_, close_channel_;
363 }; 504 };
364 505
506 void Recursive(
507 bool server_pump_first, bool server_pump_second, bool client_pump) {
508 std::vector<Worker*> workers;
509 workers.push_back(
510 new RecursiveServer(true, server_pump_first, server_pump_second));
511 workers.push_back(new RecursiveClient(client_pump, false));
512 RunTest(workers);
513 }
514
365 } // namespace 515 } // namespace
366 516
367 // Tests that the caller unblocks to answer a sync message from the receiver. 517 // Tests a server calling Send while another Send is pending.
368 TEST_F(IPCSyncChannelTest, Recursive) { 518 TEST_F(IPCSyncChannelTest, Recursive) {
519 Recursive(false, false, false);
520 Recursive(false, false, true);
521 Recursive(false, true, false);
522 Recursive(false, true, true);
523 Recursive(true, false, false);
524 Recursive(true, false, true);
525 Recursive(true, true, false);
526 Recursive(true, true, true);
527 }
528
529 //-----------------------------------------------------------------------------
530
531 namespace {
532
533 void RecursiveNoHang(
534 bool server_pump_first, bool server_pump_second, bool client_pump) {
369 std::vector<Worker*> workers; 535 std::vector<Worker*> workers;
370 workers.push_back(new RecursiveServer()); 536 workers.push_back(
371 workers.push_back(new RecursiveClient()); 537 new RecursiveServer(false, server_pump_first, server_pump_second));
538 workers.push_back(new RecursiveClient(client_pump, true));
372 RunTest(workers); 539 RunTest(workers);
373 } 540 }
374 541
542 } // namespace
543
544 // Tests that if a caller makes a sync call during an existing sync call and
545 // the receiver dies, neither of the Send() calls hang.
546 TEST_F(IPCSyncChannelTest, RecursiveNoHang) {
547 RecursiveNoHang(false, false, false);
548 RecursiveNoHang(false, false, true);
549 RecursiveNoHang(false, true, false);
550 RecursiveNoHang(false, true, true);
551 RecursiveNoHang(true, false, false);
552 RecursiveNoHang(true, false, true);
553 RecursiveNoHang(true, true, false);
554 RecursiveNoHang(true, true, true);
555 }
375 556
376 //----------------------------------------------------------------------------- 557 //-----------------------------------------------------------------------------
377 558
378 namespace { 559 namespace {
379 560
380 class MultipleServer1 : public Worker { 561 class MultipleServer1 : public Worker {
381 public: 562 public:
382 MultipleServer1() : Worker(L"test_channel1", Channel::MODE_SERVER) { } 563 MultipleServer1(bool pump_during_send)
564 : Worker(L"test_channel1", Channel::MODE_SERVER),
565 pump_during_send_(pump_during_send) { }
566
383 void Run() { 567 void Run() {
384 int answer = 0; 568 int answer = 0;
385 bool result = Send(new SyncChannelTestMsg_Double(5, &answer)); 569 IPC::SyncMessage* msg = new SyncChannelTestMsg_Double(5, &answer);
570 if (pump_during_send_)
571 msg->EnableMessagePumping();
572 bool result = Send(msg);
386 DCHECK(result); 573 DCHECK(result);
387 DCHECK(answer == 10); 574 DCHECK(answer == 10);
388 Done(); 575 Done();
389 } 576 }
577
578 bool pump_during_send_;
390 }; 579 };
391 580
392 class MultipleClient1 : public Worker { 581 class MultipleClient1 : public Worker {
393 public: 582 public:
394 MultipleClient1(Event* client1_msg_received, Event* client1_can_reply) : 583 MultipleClient1(Event* client1_msg_received, Event* client1_can_reply) :
395 Worker(L"test_channel1", Channel::MODE_CLIENT), 584 Worker(L"test_channel1", Channel::MODE_CLIENT),
396 client1_msg_received_(client1_msg_received), 585 client1_msg_received_(client1_msg_received),
397 client1_can_reply_(client1_can_reply) { } 586 client1_can_reply_(client1_can_reply) { }
398 587
399 void OnDouble(int in, int* out) { 588 void OnDouble(int in, int* out) {
(...skipping 12 matching lines...) Expand all
412 MultipleServer2() : Worker(L"test_channel2", Channel::MODE_SERVER) { } 601 MultipleServer2() : Worker(L"test_channel2", Channel::MODE_SERVER) { }
413 602
414 void OnAnswer(int* result) { 603 void OnAnswer(int* result) {
415 *result = 42; 604 *result = 42;
416 Done(); 605 Done();
417 } 606 }
418 }; 607 };
419 608
420 class MultipleClient2 : public Worker { 609 class MultipleClient2 : public Worker {
421 public: 610 public:
422 MultipleClient2(Event* client1_msg_received, Event* client1_can_reply) : 611 MultipleClient2(
423 Worker(L"test_channel2", Channel::MODE_CLIENT), 612 Event* client1_msg_received, Event* client1_can_reply,
613 bool pump_during_send)
614 : Worker(L"test_channel2", Channel::MODE_CLIENT),
424 client1_msg_received_(client1_msg_received), 615 client1_msg_received_(client1_msg_received),
425 client1_can_reply_(client1_can_reply) { } 616 client1_can_reply_(client1_can_reply),
617 pump_during_send_(pump_during_send) { }
426 618
427 void Run() { 619 void Run() {
428 int answer = 0; 620 int answer = 0;
429 client1_msg_received_->Wait(); 621 client1_msg_received_->Wait();
430 bool result = Send(new SyncChannelTestMsg_AnswerToLife(&answer)); 622 IPC::SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer);
623 if (pump_during_send_)
624 msg->EnableMessagePumping();
625 bool result = Send(msg);
431 DCHECK(result); 626 DCHECK(result);
432 DCHECK(answer == 42); 627 DCHECK(answer == 42);
433 client1_can_reply_->Set(); 628 client1_can_reply_->Set();
434 Done(); 629 Done();
435 } 630 }
436 631
437 private: 632 private:
438 Event *client1_msg_received_, *client1_can_reply_; 633 Event *client1_msg_received_, *client1_can_reply_;
634 bool pump_during_send_;
439 }; 635 };
440 636
441 } // namespace 637 void Multiple(bool server_pump, bool client_pump) {
442
443 // Tests that multiple SyncObjects on the same listener thread can unblock each
444 // other.
445 TEST_F(IPCSyncChannelTest, Multiple) {
446 std::vector<Worker*> workers; 638 std::vector<Worker*> workers;
447 639
448 // A shared worker thread so that server1 and server2 run on one thread. 640 // A shared worker thread so that server1 and server2 run on one thread.
449 base::Thread worker_thread("Multiple"); 641 base::Thread worker_thread("Multiple");
450 worker_thread.Start(); 642 worker_thread.Start();
451 643
452 // Server1 sends a sync msg to client1, which blocks the reply until 644 // Server1 sends a sync msg to client1, which blocks the reply until
453 // server2 (which runs on the same worker thread as server1) responds 645 // server2 (which runs on the same worker thread as server1) responds
454 // to a sync msg from client2. 646 // to a sync msg from client2.
455 Event client1_msg_received, client1_can_reply; 647 Event client1_msg_received, client1_can_reply;
456 648
457 Worker* worker; 649 Worker* worker;
458 650
459 worker = new MultipleServer2(); 651 worker = new MultipleServer2();
460 worker->OverrideThread(&worker_thread); 652 worker->OverrideThread(&worker_thread);
461 workers.push_back(worker); 653 workers.push_back(worker);
462 654
463 worker = new MultipleClient2( 655 worker = new MultipleClient2(
464 &client1_msg_received, &client1_can_reply); 656 &client1_msg_received, &client1_can_reply, client_pump);
465 workers.push_back(worker); 657 workers.push_back(worker);
466 658
467 worker = new MultipleServer1(); 659 worker = new MultipleServer1(server_pump);
468 worker->OverrideThread(&worker_thread); 660 worker->OverrideThread(&worker_thread);
469 workers.push_back(worker); 661 workers.push_back(worker);
470 662
471 worker = new MultipleClient1( 663 worker = new MultipleClient1(
472 &client1_msg_received, &client1_can_reply); 664 &client1_msg_received, &client1_can_reply);
473 workers.push_back(worker); 665 workers.push_back(worker);
474 666
475 RunTest(workers); 667 RunTest(workers);
476 } 668 }
477 669
670 } // namespace
671
672 // Tests that multiple SyncObjects on the same listener thread can unblock each
673 // other.
674 TEST_F(IPCSyncChannelTest, Multiple) {
675 Multiple(false, false);
676 Multiple(false, true);
677 Multiple(true, false);
678 Multiple(true, true);
679 }
478 680
479 //----------------------------------------------------------------------------- 681 //-----------------------------------------------------------------------------
480 682
481 namespace { 683 namespace {
482 684
483 class QueuedReplyServer1 : public Worker { 685 class QueuedReplyServer1 : public Worker {
484 public: 686 public:
485 QueuedReplyServer1() : Worker(L"test_channel1", Channel::MODE_SERVER) { } 687 QueuedReplyServer1(bool pump_during_send)
688 : Worker(L"test_channel1", Channel::MODE_SERVER),
689 pump_during_send_(pump_during_send) { }
486 void Run() { 690 void Run() {
487 int answer = 0; 691 int answer = 0;
488 bool result = Send(new SyncChannelTestMsg_Double(5, &answer)); 692 IPC::SyncMessage* msg = new SyncChannelTestMsg_Double(5, &answer);
693 if (pump_during_send_)
694 msg->EnableMessagePumping();
695 bool result = Send(msg);
489 DCHECK(result); 696 DCHECK(result);
490 DCHECK(answer == 10); 697 DCHECK(answer == 10);
491 Done(); 698 Done();
492 } 699 }
700
701 bool pump_during_send_;
493 }; 702 };
494 703
495 class QueuedReplyClient1 : public Worker { 704 class QueuedReplyClient1 : public Worker {
496 public: 705 public:
497 QueuedReplyClient1(Event* client1_msg_received, Event* server2_can_reply) : 706 QueuedReplyClient1(Event* client1_msg_received, Event* server2_can_reply) :
498 Worker(L"test_channel1", Channel::MODE_CLIENT), 707 Worker(L"test_channel1", Channel::MODE_CLIENT),
499 client1_msg_received_(client1_msg_received), 708 client1_msg_received_(client1_msg_received),
500 server2_can_reply_(server2_can_reply) { } 709 server2_can_reply_(server2_can_reply) { }
501 710
502 void OnDouble(int in, int* out) { 711 void OnDouble(int in, int* out) {
(...skipping 21 matching lines...) Expand all
524 733
525 *result = 42; 734 *result = 42;
526 Done(); 735 Done();
527 } 736 }
528 737
529 Event *server2_can_reply_; 738 Event *server2_can_reply_;
530 }; 739 };
531 740
532 class QueuedReplyClient2 : public Worker { 741 class QueuedReplyClient2 : public Worker {
533 public: 742 public:
534 explicit QueuedReplyClient2(Event* client1_msg_received) : 743 explicit QueuedReplyClient2(
535 Worker(L"test_channel2", Channel::MODE_CLIENT), 744 Event* client1_msg_received, bool pump_during_send)
536 client1_msg_received_(client1_msg_received) { } 745 : Worker(L"test_channel2", Channel::MODE_CLIENT),
746 client1_msg_received_(client1_msg_received),
747 pump_during_send_(pump_during_send){ }
537 748
538 void Run() { 749 void Run() {
539 int answer = 0; 750 int answer = 0;
540 client1_msg_received_->Wait(); 751 client1_msg_received_->Wait();
541 bool result = Send(new SyncChannelTestMsg_AnswerToLife(&answer)); 752 IPC::SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer);
753 if (pump_during_send_)
754 msg->EnableMessagePumping();
755 bool result = Send(msg);
542 DCHECK(result); 756 DCHECK(result);
543 DCHECK(answer == 42); 757 DCHECK(answer == 42);
544 Done(); 758 Done();
545 } 759 }
546 760
547 private:
548 Event *client1_msg_received_; 761 Event *client1_msg_received_;
762 bool pump_during_send_;
549 }; 763 };
550 764
551 } // namespace 765 void QueuedReply(bool server_pump, bool client_pump) {
552
553 // While a blocking send is in progress, the listener thread might answer other
554 // synchronous messages. This tests that if during the response to another
555 // message the reply to the original messages comes, it is queued up correctly
556 // and the original Send is unblocked later.
557 TEST_F(IPCSyncChannelTest, QueuedReply) {
558 std::vector<Worker*> workers; 766 std::vector<Worker*> workers;
559 767
560 // A shared worker thread so that server1 and server2 run on one thread. 768 // A shared worker thread so that server1 and server2 run on one thread.
561 base::Thread worker_thread("QueuedReply"); 769 base::Thread worker_thread("QueuedReply");
562 worker_thread.Start(); 770 worker_thread.Start();
563 771
564 Event client1_msg_received, server2_can_reply; 772 Event client1_msg_received, server2_can_reply;
565 773
566 Worker* worker; 774 Worker* worker;
567 775
568 worker = new QueuedReplyServer2(&server2_can_reply); 776 worker = new QueuedReplyServer2(&server2_can_reply);
569 worker->OverrideThread(&worker_thread); 777 worker->OverrideThread(&worker_thread);
570 workers.push_back(worker); 778 workers.push_back(worker);
571 779
572 worker = new QueuedReplyClient2(&client1_msg_received); 780 worker = new QueuedReplyClient2(&client1_msg_received, client_pump);
573 workers.push_back(worker); 781 workers.push_back(worker);
574 782
575 worker = new QueuedReplyServer1(); 783 worker = new QueuedReplyServer1(server_pump);
576 worker->OverrideThread(&worker_thread); 784 worker->OverrideThread(&worker_thread);
577 workers.push_back(worker); 785 workers.push_back(worker);
578 786
579 worker = new QueuedReplyClient1( 787 worker = new QueuedReplyClient1(
580 &client1_msg_received, &server2_can_reply); 788 &client1_msg_received, &server2_can_reply);
581 workers.push_back(worker); 789 workers.push_back(worker);
582 790
583 RunTest(workers); 791 RunTest(workers);
584 } 792 }
585 793
794 } // namespace
795
796 // While a blocking send is in progress, the listener thread might answer other
797 // synchronous messages. This tests that if during the response to another
798 // message the reply to the original messages comes, it is queued up correctly
799 // and the original Send is unblocked later.
800 TEST_F(IPCSyncChannelTest, QueuedReply) {
801 QueuedReply(false, false);
802 QueuedReply(false, true);
803 QueuedReply(true, false);
804 QueuedReply(true, true);
805 }
586 806
587 //----------------------------------------------------------------------------- 807 //-----------------------------------------------------------------------------
588 808
589 namespace { 809 namespace {
590 810
591 class BadServer : public Worker { 811 class BadServer : public Worker {
592 public: 812 public:
593 BadServer() : Worker(Channel::MODE_SERVER, "simpler_server") { } 813 BadServer(bool pump_during_send)
814 : Worker(Channel::MODE_SERVER, "simpler_server"),
815 pump_during_send_(pump_during_send) { }
594 void Run() { 816 void Run() {
595 int answer = 0; 817 int answer = 0;
596 818
597 Message* msg = new SyncMessage(MSG_ROUTING_CONTROL, 819 IPC::SyncMessage* msg = new SyncMessage(
598 SyncChannelTestMsg_Double::ID, 820 MSG_ROUTING_CONTROL, SyncChannelTestMsg_Double::ID,
599 Message::PRIORITY_NORMAL, 821 Message::PRIORITY_NORMAL, NULL);
600 NULL); 822 if (pump_during_send_)
823 msg->EnableMessagePumping();
824
601 // Temporarily set the minimum logging very high so that the assertion 825 // Temporarily set the minimum logging very high so that the assertion
602 // in ipc_message_utils doesn't fire. 826 // in ipc_message_utils doesn't fire.
603 int log_level = logging::GetMinLogLevel(); 827 int log_level = logging::GetMinLogLevel();
604 logging::SetMinLogLevel(kint32max); 828 logging::SetMinLogLevel(kint32max);
605 bool result = Send(msg); 829 bool result = Send(msg);
606 logging::SetMinLogLevel(log_level); 830 logging::SetMinLogLevel(log_level);
607 DCHECK(!result); 831 DCHECK(!result);
608 832
609 // Need to send another message to get the client to call Done(). 833 // Need to send another message to get the client to call Done().
610 result = Send(new SyncChannelTestMsg_AnswerToLife(&answer)); 834 result = Send(new SyncChannelTestMsg_AnswerToLife(&answer));
611 DCHECK(result); 835 DCHECK(result);
612 DCHECK(answer == 42); 836 DCHECK(answer == 42);
613 837
614 Done(); 838 Done();
615 } 839 }
840
841 bool pump_during_send_;
616 }; 842 };
617 843
844 void BadMessage(bool pump_during_send) {
845 std::vector<Worker*> workers;
846 workers.push_back(new BadServer(pump_during_send));
847 workers.push_back(new SimpleClient());
848 RunTest(workers);
849 }
850
618 } // namespace 851 } // namespace
619 852
620 // Tests that if a message is not serialized correctly, the Send() will fail. 853 // Tests that if a message is not serialized correctly, the Send() will fail.
621 TEST_F(IPCSyncChannelTest, BadMessage) { 854 TEST_F(IPCSyncChannelTest, BadMessage) {
622 std::vector<Worker*> workers; 855 BadMessage(false);
623 workers.push_back(new BadServer()); 856 BadMessage(true);
624 workers.push_back(new SimpleClient());
625 RunTest(workers);
626 } 857 }
627 858
628
629 //----------------------------------------------------------------------------- 859 //-----------------------------------------------------------------------------
630 860
631 namespace { 861 namespace {
632 862
633 class ChattyRecursiveClient : public Worker { 863 class ChattyClient : public Worker {
634 public: 864 public:
635 ChattyRecursiveClient() : 865 ChattyClient() :
636 Worker(Channel::MODE_CLIENT, "chatty_recursive_client") { } 866 Worker(Channel::MODE_CLIENT, "chatty_client") { }
637 867
638 void OnAnswer(int* answer) { 868 void OnAnswer(int* answer) {
639 // The PostMessage limit is 10k. Send 20% more than that. 869 // The PostMessage limit is 10k. Send 20% more than that.
640 const int kMessageLimit = 10000; 870 const int kMessageLimit = 10000;
641 const int kMessagesToSend = kMessageLimit * 120 / 100; 871 const int kMessagesToSend = kMessageLimit * 120 / 100;
642 for (int i = 0; i < kMessagesToSend; ++i) { 872 for (int i = 0; i < kMessagesToSend; ++i) {
643 bool result = Send(new SyncChannelTestMsg_Double(21, answer)); 873 bool result = Send(new SyncChannelTestMsg_Double(21, answer));
644 DCHECK(result); 874 DCHECK(result);
645 if (!result) 875 if (!result)
646 break; 876 break;
647 } 877 }
648 Done(); 878 Done();
649 } 879 }
650 }; 880 };
651 881
882 void ChattyServer(bool pump_during_send) {
883 std::vector<Worker*> workers;
884 workers.push_back(new UnblockServer(pump_during_send));
885 workers.push_back(new ChattyClient());
886 RunTest(workers);
887 }
888
652 } // namespace 889 } // namespace
653 890
654 // Tests http://b/issue?id=1093251 - that sending lots of sync messages while 891 // Tests http://b/issue?id=1093251 - that sending lots of sync messages while
655 // the receiver is waiting for a sync reply does not overflow the PostMessage 892 // the receiver is waiting for a sync reply does not overflow the PostMessage
656 // queue. 893 // queue.
657 TEST_F(IPCSyncChannelTest, ChattyServer) { 894 TEST_F(IPCSyncChannelTest, ChattyServer) {
658 std::vector<Worker*> workers; 895 ChattyServer(false);
659 workers.push_back(new RecursiveServer()); 896 ChattyServer(true);
660 workers.push_back(new ChattyRecursiveClient());
661 RunTest(workers);
662 } 897 }
663 898
664
665 //------------------------------------------------------------------------------ 899 //------------------------------------------------------------------------------
666 900
667 namespace { 901 namespace {
668 902
669 class TimeoutServer : public Worker { 903 class TimeoutServer : public Worker {
670 public: 904 public:
671 TimeoutServer(int timeout_ms, 905 TimeoutServer(int timeout_ms,
672 std::vector<bool> timeout_seq) 906 std::vector<bool> timeout_seq,
907 bool pump_during_send)
673 : Worker(Channel::MODE_SERVER, "timeout_server"), 908 : Worker(Channel::MODE_SERVER, "timeout_server"),
674 timeout_ms_(timeout_ms), 909 timeout_ms_(timeout_ms),
675 timeout_seq_(timeout_seq) { 910 timeout_seq_(timeout_seq),
911 pump_during_send_(pump_during_send) {
676 } 912 }
677 913
678 void Run() { 914 void Run() {
679 for (std::vector<bool>::const_iterator iter = timeout_seq_.begin(); 915 for (std::vector<bool>::const_iterator iter = timeout_seq_.begin();
680 iter != timeout_seq_.end(); ++iter) { 916 iter != timeout_seq_.end(); ++iter) {
681 int answer = 0; 917 int answer = 0;
682 bool result = 918 IPC::SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer);
683 SendWithTimeout(new SyncChannelTestMsg_AnswerToLife(&answer), 919 if (pump_during_send_)
684 timeout_ms_); 920 msg->EnableMessagePumping();
921 bool result = SendWithTimeout(msg, timeout_ms_);
685 if (*iter) { 922 if (*iter) {
686 // Time-out expected. 923 // Time-out expected.
687 DCHECK(!result); 924 DCHECK(!result);
688 DCHECK(answer == 0); 925 DCHECK(answer == 0);
689 } else { 926 } else {
690 DCHECK(result); 927 DCHECK(result);
691 DCHECK(answer == 42); 928 DCHECK(answer == 42);
692 } 929 }
693 } 930 }
694 Done(); 931 Done();
695 } 932 }
696 933
697 private: 934 private:
698 int timeout_ms_; 935 int timeout_ms_;
699 std::vector<bool> timeout_seq_; 936 std::vector<bool> timeout_seq_;
937 bool pump_during_send_;
700 }; 938 };
701 939
702 class UnresponsiveClient : public Worker { 940 class UnresponsiveClient : public Worker {
703 public: 941 public:
704 UnresponsiveClient(std::vector<bool> timeout_seq) 942 UnresponsiveClient(std::vector<bool> timeout_seq)
705 : Worker(Channel::MODE_CLIENT, "unresponsive_client"), 943 : Worker(Channel::MODE_CLIENT, "unresponsive_client"),
706 timeout_seq_(timeout_seq) { 944 timeout_seq_(timeout_seq) {
707 } 945 }
708 946
709 void OnAnswerDelay(Message* reply_msg) { 947 void OnAnswerDelay(Message* reply_msg) {
710 DCHECK(!timeout_seq_.empty()); 948 DCHECK(!timeout_seq_.empty());
711 if (!timeout_seq_[0]) { 949 if (!timeout_seq_[0]) {
712 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42); 950 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42);
713 Send(reply_msg); 951 Send(reply_msg);
714 } else { 952 } else {
715 // Don't reply. 953 // Don't reply.
716 delete reply_msg; 954 delete reply_msg;
717 } 955 }
718 timeout_seq_.erase(timeout_seq_.begin()); 956 timeout_seq_.erase(timeout_seq_.begin());
719 if (timeout_seq_.empty()) 957 if (timeout_seq_.empty())
720 Done(); 958 Done();
721 } 959 }
722 960
723 private: 961 private:
724 // Whether we should time-out or respond to the various messages we receive. 962 // Whether we should time-out or respond to the various messages we receive.
725 std::vector<bool> timeout_seq_; 963 std::vector<bool> timeout_seq_;
726 }; 964 };
727 965
728 } // namespace 966 void SendWithTimeoutOK(bool pump_during_send) {
729
730 // Tests that SendWithTimeout does not time-out if the response comes back fast
731 // enough.
732 TEST_F(IPCSyncChannelTest, SendWithTimeoutOK) {
733 std::vector<Worker*> workers; 967 std::vector<Worker*> workers;
734 std::vector<bool> timeout_seq; 968 std::vector<bool> timeout_seq;
735 timeout_seq.push_back(false); 969 timeout_seq.push_back(false);
736 timeout_seq.push_back(false); 970 timeout_seq.push_back(false);
737 timeout_seq.push_back(false); 971 timeout_seq.push_back(false);
738 workers.push_back(new TimeoutServer(5000, timeout_seq)); 972 workers.push_back(new TimeoutServer(5000, timeout_seq, pump_during_send));
739 workers.push_back(new SimpleClient()); 973 workers.push_back(new SimpleClient());
740 RunTest(workers); 974 RunTest(workers);
741 } 975 }
742 976
743 // Tests that SendWithTimeout does time-out. 977 void SendWithTimeoutTimeout(bool pump_during_send) {
744 TEST_F(IPCSyncChannelTest, SendWithTimeoutTimeout) {
745 std::vector<Worker*> workers; 978 std::vector<Worker*> workers;
746 std::vector<bool> timeout_seq; 979 std::vector<bool> timeout_seq;
747 timeout_seq.push_back(true); 980 timeout_seq.push_back(true);
748 timeout_seq.push_back(false); 981 timeout_seq.push_back(false);
749 timeout_seq.push_back(false); 982 timeout_seq.push_back(false);
750 workers.push_back(new TimeoutServer(100, timeout_seq)); 983 workers.push_back(new TimeoutServer(100, timeout_seq, pump_during_send));
751 workers.push_back(new UnresponsiveClient(timeout_seq)); 984 workers.push_back(new UnresponsiveClient(timeout_seq));
752 RunTest(workers); 985 RunTest(workers);
753 } 986 }
754 987
755 // Sends some message that time-out and some that succeed. 988 void SendWithTimeoutMixedOKAndTimeout(bool pump_during_send) {
756 TEST_F(IPCSyncChannelTest, SendWithTimeoutMixedOKAndTimeout) {
757 std::vector<Worker*> workers; 989 std::vector<Worker*> workers;
758 std::vector<bool> timeout_seq; 990 std::vector<bool> timeout_seq;
759 timeout_seq.push_back(true); 991 timeout_seq.push_back(true);
760 timeout_seq.push_back(false); 992 timeout_seq.push_back(false);
761 timeout_seq.push_back(false); 993 timeout_seq.push_back(false);
762 timeout_seq.push_back(true); 994 timeout_seq.push_back(true);
763 timeout_seq.push_back(false); 995 timeout_seq.push_back(false);
764 workers.push_back(new TimeoutServer(100, timeout_seq)); 996 workers.push_back(new TimeoutServer(100, timeout_seq, pump_during_send));
765 workers.push_back(new UnresponsiveClient(timeout_seq)); 997 workers.push_back(new UnresponsiveClient(timeout_seq));
766 RunTest(workers); 998 RunTest(workers);
767 } 999 }
1000
1001 } // namespace
1002
1003 // Tests that SendWithTimeout does not time-out if the response comes back fast
1004 // enough.
1005 TEST_F(IPCSyncChannelTest, SendWithTimeoutOK) {
1006 SendWithTimeoutOK(false);
1007 SendWithTimeoutOK(true);
1008 }
1009
1010 // Tests that SendWithTimeout does time-out.
1011 TEST_F(IPCSyncChannelTest, SendWithTimeoutTimeout) {
1012 SendWithTimeoutTimeout(false);
1013 SendWithTimeoutTimeout(true);
1014 }
1015
1016 // Sends some message that time-out and some that succeed.
1017 TEST_F(IPCSyncChannelTest, SendWithTimeoutMixedOKAndTimeout) {
1018 SendWithTimeoutMixedOKAndTimeout(false);
1019 SendWithTimeoutMixedOKAndTimeout(true);
1020 }
OLDNEW
« no previous file with comments | « chrome/common/ipc_sync_channel.cc ('k') | chrome/common/ipc_sync_message.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698