1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ipc/ipc_sync_channel.h"
10 #include "base/basictypes.h"
11 #include "base/bind.h"
12 #include "base/location.h"
13 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/process/process_handle.h"
16 #include "base/run_loop.h"
17 #include "base/single_thread_task_runner.h"
18 #include "base/strings/string_util.h"
19 #include "base/synchronization/waitable_event.h"
20 #include "base/thread_task_runner_handle.h"
21 #include "base/threading/platform_thread.h"
22 #include "base/threading/thread.h"
23 #include "ipc/ipc_listener.h"
24 #include "ipc/ipc_message.h"
25 #include "ipc/ipc_sender.h"
26 #include "ipc/ipc_sync_message_filter.h"
27 #include "ipc/ipc_sync_message_unittest.h"
28 #include "testing/gtest/include/gtest/gtest.h"
30 using base::WaitableEvent
;
35 // Base class for a "process" with listener and IPC threads.
36 class Worker
: public Listener
, public Sender
{
38 // Will create a channel without a name.
39 Worker(Channel::Mode mode
, const std::string
& thread_name
)
40 : done_(new WaitableEvent(false, false)),
41 channel_created_(new WaitableEvent(false, false)),
43 ipc_thread_((thread_name
+ "_ipc").c_str()),
44 listener_thread_((thread_name
+ "_listener").c_str()),
45 overrided_thread_(NULL
),
46 shutdown_event_(true, false),
50 // Will create a named channel and use this name for the threads' name.
51 Worker(const std::string
& channel_name
, Channel::Mode mode
)
52 : done_(new WaitableEvent(false, false)),
53 channel_created_(new WaitableEvent(false, false)),
54 channel_name_(channel_name
),
56 ipc_thread_((channel_name
+ "_ipc").c_str()),
57 listener_thread_((channel_name
+ "_listener").c_str()),
58 overrided_thread_(NULL
),
59 shutdown_event_(true, false),
64 // Shutdown() must be called before destruction.
69 bool Send(Message
* msg
) override
{ return channel_
->Send(msg
); }
70 void WaitForChannelCreation() { channel_created_
->Wait(); }
72 DCHECK(base::MessageLoop::current() == ListenerThread()->message_loop());
76 StartThread(&listener_thread_
, base::MessageLoop::TYPE_DEFAULT
);
77 ListenerThread()->task_runner()->PostTask(
78 FROM_HERE
, base::Bind(&Worker::OnStart
, this));
81 // The IPC thread needs to outlive SyncChannel. We can't do this in
82 // ~Worker(), since that'll reset the vtable pointer (to Worker's), which
83 // may result in a race conditions. See http://crbug.com/25841.
84 WaitableEvent
listener_done(false, false), ipc_done(false, false);
85 ListenerThread()->task_runner()->PostTask(
86 FROM_HERE
, base::Bind(&Worker::OnListenerThreadShutdown1
, this,
87 &listener_done
, &ipc_done
));
91 listener_thread_
.Stop();
94 void OverrideThread(base::Thread
* overrided_thread
) {
95 DCHECK(overrided_thread_
== NULL
);
96 overrided_thread_
= overrided_thread
;
98 bool SendAnswerToLife(bool pump
, bool succeed
) {
100 SyncMessage
* msg
= new SyncChannelTestMsg_AnswerToLife(&answer
);
102 msg
->EnableMessagePumping();
103 bool result
= Send(msg
);
104 DCHECK_EQ(result
, succeed
);
105 DCHECK_EQ(answer
, (succeed
? 42 : 0));
108 bool SendDouble(bool pump
, bool succeed
) {
110 SyncMessage
* msg
= new SyncChannelTestMsg_Double(5, &answer
);
112 msg
->EnableMessagePumping();
113 bool result
= Send(msg
);
114 DCHECK_EQ(result
, succeed
);
115 DCHECK_EQ(answer
, (succeed
? 10 : 0));
118 const std::string
& channel_name() { return channel_name_
; }
119 Channel::Mode
mode() { return mode_
; }
120 WaitableEvent
* done_event() { return done_
.get(); }
121 WaitableEvent
* shutdown_event() { return &shutdown_event_
; }
122 void ResetChannel() { channel_
.reset(); }
123 // Derived classes need to call this when they've completed their part of
125 void Done() { done_
->Signal(); }
128 SyncChannel
* channel() { return channel_
.get(); }
129 // Functions for derived classes to implement if they wish.
130 virtual void Run() { }
131 virtual void OnAnswer(int* answer
) { NOTREACHED(); }
132 virtual void OnAnswerDelay(Message
* reply_msg
) {
133 // The message handler map below can only take one entry for
134 // SyncChannelTestMsg_AnswerToLife, so since some classes want
135 // the normal version while other want the delayed reply, we
136 // call the normal version if the derived class didn't override
140 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg
, answer
);
143 virtual void OnDouble(int in
, int* out
) { NOTREACHED(); }
144 virtual void OnDoubleDelay(int in
, Message
* reply_msg
) {
146 OnDouble(in
, &result
);
147 SyncChannelTestMsg_Double::WriteReplyParams(reply_msg
, result
);
151 virtual void OnNestedTestMsg(Message
* reply_msg
) {
155 virtual SyncChannel
* CreateChannel() {
156 scoped_ptr
<SyncChannel
> channel
= SyncChannel::Create(
157 channel_name_
, mode_
, this, ipc_thread_
.task_runner().get(), true,
158 &shutdown_event_
, nullptr);
159 return channel
.release();
162 base::Thread
* ListenerThread() {
163 return overrided_thread_
? overrided_thread_
: &listener_thread_
;
166 const base::Thread
& ipc_thread() const { return ipc_thread_
; }
169 // Called on the listener thread to create the sync channel.
171 // Link ipc_thread_, listener_thread_ and channel_ altogether.
172 StartThread(&ipc_thread_
, base::MessageLoop::TYPE_IO
);
173 channel_
.reset(CreateChannel());
174 channel_created_
->Signal();
178 void OnListenerThreadShutdown1(WaitableEvent
* listener_event
,
179 WaitableEvent
* ipc_event
) {
180 // SyncChannel needs to be destructed on the thread that it was created on.
183 base::RunLoop().RunUntilIdle();
185 ipc_thread_
.message_loop()->PostTask(
186 FROM_HERE
, base::Bind(&Worker::OnIPCThreadShutdown
, this,
187 listener_event
, ipc_event
));
190 void OnIPCThreadShutdown(WaitableEvent
* listener_event
,
191 WaitableEvent
* ipc_event
) {
192 base::RunLoop().RunUntilIdle();
195 listener_thread_
.task_runner()->PostTask(
197 base::Bind(&Worker::OnListenerThreadShutdown2
, this, listener_event
));
200 void OnListenerThreadShutdown2(WaitableEvent
* listener_event
) {
201 base::RunLoop().RunUntilIdle();
202 listener_event
->Signal();
205 bool OnMessageReceived(const Message
& message
) override
{
206 IPC_BEGIN_MESSAGE_MAP(Worker
, message
)
207 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_Double
, OnDoubleDelay
)
208 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_AnswerToLife
,
210 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelNestedTestMsg_String
,
212 IPC_END_MESSAGE_MAP()
216 void StartThread(base::Thread
* thread
, base::MessageLoop::Type type
) {
217 base::Thread::Options options
;
218 options
.message_loop_type
= type
;
219 thread
->StartWithOptions(options
);
222 scoped_ptr
<WaitableEvent
> done_
;
223 scoped_ptr
<WaitableEvent
> channel_created_
;
224 std::string channel_name_
;
226 scoped_ptr
<SyncChannel
> channel_
;
227 base::Thread ipc_thread_
;
228 base::Thread listener_thread_
;
229 base::Thread
* overrided_thread_
;
231 base::WaitableEvent shutdown_event_
;
235 DISALLOW_COPY_AND_ASSIGN(Worker
);
239 // Starts the test with the given workers. This function deletes the workers
241 void RunTest(std::vector
<Worker
*> workers
) {
242 // First we create the workers that are channel servers, or else the other
243 // workers' channel initialization might fail because the pipe isn't created..
244 for (size_t i
= 0; i
< workers
.size(); ++i
) {
245 if (workers
[i
]->mode() & Channel::MODE_SERVER_FLAG
) {
247 workers
[i
]->WaitForChannelCreation();
251 // now create the clients
252 for (size_t i
= 0; i
< workers
.size(); ++i
) {
253 if (workers
[i
]->mode() & Channel::MODE_CLIENT_FLAG
)
257 // wait for all the workers to finish
258 for (size_t i
= 0; i
< workers
.size(); ++i
)
259 workers
[i
]->done_event()->Wait();
261 for (size_t i
= 0; i
< workers
.size(); ++i
) {
262 workers
[i
]->Shutdown();
267 class IPCSyncChannelTest
: public testing::Test
{
269 base::MessageLoop message_loop_
;
272 //------------------------------------------------------------------------------
274 class SimpleServer
: public Worker
{
276 explicit SimpleServer(bool pump_during_send
)
277 : Worker(Channel::MODE_SERVER
, "simpler_server"),
278 pump_during_send_(pump_during_send
) { }
279 void Run() override
{
280 SendAnswerToLife(pump_during_send_
, true);
284 bool pump_during_send_
;
287 class SimpleClient
: public Worker
{
289 SimpleClient() : Worker(Channel::MODE_CLIENT
, "simple_client") { }
291 void OnAnswer(int* answer
) override
{
297 void Simple(bool pump_during_send
) {
298 std::vector
<Worker
*> workers
;
299 workers
.push_back(new SimpleServer(pump_during_send
));
300 workers
.push_back(new SimpleClient());
304 #if defined(OS_ANDROID)
305 #define MAYBE_Simple DISABLED_Simple
307 #define MAYBE_Simple Simple
309 // Tests basic synchronous call
310 TEST_F(IPCSyncChannelTest
, MAYBE_Simple
) {
315 //------------------------------------------------------------------------------
317 // Worker classes which override how the sync channel is created to use the
318 // two-step initialization (calling the lightweight constructor and then
319 // ChannelProxy::Init separately) process.
320 class TwoStepServer
: public Worker
{
322 explicit TwoStepServer(bool create_pipe_now
)
323 : Worker(Channel::MODE_SERVER
, "simpler_server"),
324 create_pipe_now_(create_pipe_now
) { }
326 void Run() override
{
327 SendAnswerToLife(false, true);
331 SyncChannel
* CreateChannel() override
{
332 SyncChannel
* channel
=
333 SyncChannel::Create(channel_name(), mode(), this,
334 ipc_thread().task_runner().get(), create_pipe_now_
,
335 shutdown_event(), nullptr).release();
339 bool create_pipe_now_
;
342 class TwoStepClient
: public Worker
{
344 TwoStepClient(bool create_pipe_now
)
345 : Worker(Channel::MODE_CLIENT
, "simple_client"),
346 create_pipe_now_(create_pipe_now
) { }
348 void OnAnswer(int* answer
) override
{
353 SyncChannel
* CreateChannel() override
{
354 SyncChannel
* channel
=
355 SyncChannel::Create(channel_name(), mode(), this,
356 ipc_thread().task_runner().get(), create_pipe_now_
,
357 shutdown_event(), nullptr).release();
361 bool create_pipe_now_
;
364 void TwoStep(bool create_server_pipe_now
, bool create_client_pipe_now
) {
365 std::vector
<Worker
*> workers
;
366 workers
.push_back(new TwoStepServer(create_server_pipe_now
));
367 workers
.push_back(new TwoStepClient(create_client_pipe_now
));
371 // Tests basic two-step initialization, where you call the lightweight
372 // constructor then Init.
373 TEST_F(IPCSyncChannelTest
, TwoStepInitialization
) {
374 TwoStep(false, false);
375 TwoStep(false, true);
376 TwoStep(true, false);
380 //------------------------------------------------------------------------------
382 class DelayClient
: public Worker
{
384 DelayClient() : Worker(Channel::MODE_CLIENT
, "delay_client") { }
386 void OnAnswerDelay(Message
* reply_msg
) override
{
387 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg
, 42);
393 void DelayReply(bool pump_during_send
) {
394 std::vector
<Worker
*> workers
;
395 workers
.push_back(new SimpleServer(pump_during_send
));
396 workers
.push_back(new DelayClient());
400 // Tests that asynchronous replies work
401 TEST_F(IPCSyncChannelTest
, DelayReply
) {
406 //------------------------------------------------------------------------------
408 class NoHangServer
: public Worker
{
410 NoHangServer(WaitableEvent
* got_first_reply
, bool pump_during_send
)
411 : Worker(Channel::MODE_SERVER
, "no_hang_server"),
412 got_first_reply_(got_first_reply
),
413 pump_during_send_(pump_during_send
) { }
414 void Run() override
{
415 SendAnswerToLife(pump_during_send_
, true);
416 got_first_reply_
->Signal();
418 SendAnswerToLife(pump_during_send_
, false);
422 WaitableEvent
* got_first_reply_
;
423 bool pump_during_send_
;
426 class NoHangClient
: public Worker
{
428 explicit NoHangClient(WaitableEvent
* got_first_reply
)
429 : Worker(Channel::MODE_CLIENT
, "no_hang_client"),
430 got_first_reply_(got_first_reply
) { }
432 void OnAnswerDelay(Message
* reply_msg
) override
{
433 // Use the DELAY_REPLY macro so that we can force the reply to be sent
434 // before this function returns (when the channel will be reset).
435 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg
, 42);
437 got_first_reply_
->Wait();
442 WaitableEvent
* got_first_reply_
;
445 void NoHang(bool pump_during_send
) {
446 WaitableEvent
got_first_reply(false, false);
447 std::vector
<Worker
*> workers
;
448 workers
.push_back(new NoHangServer(&got_first_reply
, pump_during_send
));
449 workers
.push_back(new NoHangClient(&got_first_reply
));
453 // Tests that caller doesn't hang if receiver dies
454 TEST_F(IPCSyncChannelTest
, NoHang
) {
459 //------------------------------------------------------------------------------
461 class UnblockServer
: public Worker
{
463 UnblockServer(bool pump_during_send
, bool delete_during_send
)
464 : Worker(Channel::MODE_SERVER
, "unblock_server"),
465 pump_during_send_(pump_during_send
),
466 delete_during_send_(delete_during_send
) { }
467 void Run() override
{
468 if (delete_during_send_
) {
469 // Use custom code since race conditions mean the answer may or may not be
472 SyncMessage
* msg
= new SyncChannelTestMsg_AnswerToLife(&answer
);
473 if (pump_during_send_
)
474 msg
->EnableMessagePumping();
477 SendAnswerToLife(pump_during_send_
, true);
482 void OnDoubleDelay(int in
, Message
* reply_msg
) override
{
483 SyncChannelTestMsg_Double::WriteReplyParams(reply_msg
, in
* 2);
485 if (delete_during_send_
)
489 bool pump_during_send_
;
490 bool delete_during_send_
;
493 class UnblockClient
: public Worker
{
495 explicit UnblockClient(bool pump_during_send
)
496 : Worker(Channel::MODE_CLIENT
, "unblock_client"),
497 pump_during_send_(pump_during_send
) { }
499 void OnAnswer(int* answer
) override
{
500 SendDouble(pump_during_send_
, true);
505 bool pump_during_send_
;
508 void Unblock(bool server_pump
, bool client_pump
, bool delete_during_send
) {
509 std::vector
<Worker
*> workers
;
510 workers
.push_back(new UnblockServer(server_pump
, delete_during_send
));
511 workers
.push_back(new UnblockClient(client_pump
));
515 // Tests that the caller unblocks to answer a sync message from the receiver.
516 TEST_F(IPCSyncChannelTest
, Unblock
) {
517 Unblock(false, false, false);
518 Unblock(false, true, false);
519 Unblock(true, false, false);
520 Unblock(true, true, false);
523 //------------------------------------------------------------------------------
525 #if defined(OS_ANDROID)
526 #define MAYBE_ChannelDeleteDuringSend DISABLED_ChannelDeleteDuringSend
528 #define MAYBE_ChannelDeleteDuringSend ChannelDeleteDuringSend
530 // Tests that the the SyncChannel object can be deleted during a Send.
531 TEST_F(IPCSyncChannelTest
, MAYBE_ChannelDeleteDuringSend
) {
532 Unblock(false, false, true);
533 Unblock(false, true, true);
534 Unblock(true, false, true);
535 Unblock(true, true, true);
538 //------------------------------------------------------------------------------
540 class RecursiveServer
: public Worker
{
542 RecursiveServer(bool expected_send_result
, bool pump_first
, bool pump_second
)
543 : Worker(Channel::MODE_SERVER
, "recursive_server"),
544 expected_send_result_(expected_send_result
),
545 pump_first_(pump_first
), pump_second_(pump_second
) {}
546 void Run() override
{
547 SendDouble(pump_first_
, expected_send_result_
);
551 void OnDouble(int in
, int* out
) override
{
553 SendAnswerToLife(pump_second_
, expected_send_result_
);
556 bool expected_send_result_
, pump_first_
, pump_second_
;
559 class RecursiveClient
: public Worker
{
561 RecursiveClient(bool pump_during_send
, bool close_channel
)
562 : Worker(Channel::MODE_CLIENT
, "recursive_client"),
563 pump_during_send_(pump_during_send
), close_channel_(close_channel
) {}
565 void OnDoubleDelay(int in
, Message
* reply_msg
) override
{
566 SendDouble(pump_during_send_
, !close_channel_
);
567 if (close_channel_
) {
570 SyncChannelTestMsg_Double::WriteReplyParams(reply_msg
, in
* 2);
576 void OnAnswerDelay(Message
* reply_msg
) override
{
577 if (close_channel_
) {
581 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg
, 42);
586 bool pump_during_send_
, close_channel_
;
590 bool server_pump_first
, bool server_pump_second
, bool client_pump
) {
591 std::vector
<Worker
*> workers
;
593 new RecursiveServer(true, server_pump_first
, server_pump_second
));
594 workers
.push_back(new RecursiveClient(client_pump
, false));
598 // Tests a server calling Send while another Send is pending.
599 TEST_F(IPCSyncChannelTest
, Recursive
) {
600 Recursive(false, false, false);
601 Recursive(false, false, true);
602 Recursive(false, true, false);
603 Recursive(false, true, true);
604 Recursive(true, false, false);
605 Recursive(true, false, true);
606 Recursive(true, true, false);
607 Recursive(true, true, true);
610 //------------------------------------------------------------------------------
612 void RecursiveNoHang(
613 bool server_pump_first
, bool server_pump_second
, bool client_pump
) {
614 std::vector
<Worker
*> workers
;
616 new RecursiveServer(false, server_pump_first
, server_pump_second
));
617 workers
.push_back(new RecursiveClient(client_pump
, true));
621 // Tests that if a caller makes a sync call during an existing sync call and
622 // the receiver dies, neither of the Send() calls hang.
623 TEST_F(IPCSyncChannelTest
, RecursiveNoHang
) {
624 RecursiveNoHang(false, false, false);
625 RecursiveNoHang(false, false, true);
626 RecursiveNoHang(false, true, false);
627 RecursiveNoHang(false, true, true);
628 RecursiveNoHang(true, false, false);
629 RecursiveNoHang(true, false, true);
630 RecursiveNoHang(true, true, false);
631 RecursiveNoHang(true, true, true);
634 //------------------------------------------------------------------------------
636 class MultipleServer1
: public Worker
{
638 explicit MultipleServer1(bool pump_during_send
)
639 : Worker("test_channel1", Channel::MODE_SERVER
),
640 pump_during_send_(pump_during_send
) { }
642 void Run() override
{
643 SendDouble(pump_during_send_
, true);
647 bool pump_during_send_
;
650 class MultipleClient1
: public Worker
{
652 MultipleClient1(WaitableEvent
* client1_msg_received
,
653 WaitableEvent
* client1_can_reply
) :
654 Worker("test_channel1", Channel::MODE_CLIENT
),
655 client1_msg_received_(client1_msg_received
),
656 client1_can_reply_(client1_can_reply
) { }
658 void OnDouble(int in
, int* out
) override
{
659 client1_msg_received_
->Signal();
661 client1_can_reply_
->Wait();
666 WaitableEvent
*client1_msg_received_
, *client1_can_reply_
;
669 class MultipleServer2
: public Worker
{
671 MultipleServer2() : Worker("test_channel2", Channel::MODE_SERVER
) { }
673 void OnAnswer(int* result
) override
{
679 class MultipleClient2
: public Worker
{
682 WaitableEvent
* client1_msg_received
, WaitableEvent
* client1_can_reply
,
683 bool pump_during_send
)
684 : Worker("test_channel2", Channel::MODE_CLIENT
),
685 client1_msg_received_(client1_msg_received
),
686 client1_can_reply_(client1_can_reply
),
687 pump_during_send_(pump_during_send
) { }
689 void Run() override
{
690 client1_msg_received_
->Wait();
691 SendAnswerToLife(pump_during_send_
, true);
692 client1_can_reply_
->Signal();
697 WaitableEvent
*client1_msg_received_
, *client1_can_reply_
;
698 bool pump_during_send_
;
701 void Multiple(bool server_pump
, bool client_pump
) {
702 std::vector
<Worker
*> workers
;
704 // A shared worker thread so that server1 and server2 run on one thread.
705 base::Thread
worker_thread("Multiple");
706 ASSERT_TRUE(worker_thread
.Start());
708 // Server1 sends a sync msg to client1, which blocks the reply until
709 // server2 (which runs on the same worker thread as server1) responds
710 // to a sync msg from client2.
711 WaitableEvent
client1_msg_received(false, false);
712 WaitableEvent
client1_can_reply(false, false);
716 worker
= new MultipleServer2();
717 worker
->OverrideThread(&worker_thread
);
718 workers
.push_back(worker
);
720 worker
= new MultipleClient2(
721 &client1_msg_received
, &client1_can_reply
, client_pump
);
722 workers
.push_back(worker
);
724 worker
= new MultipleServer1(server_pump
);
725 worker
->OverrideThread(&worker_thread
);
726 workers
.push_back(worker
);
728 worker
= new MultipleClient1(
729 &client1_msg_received
, &client1_can_reply
);
730 workers
.push_back(worker
);
735 // Tests that multiple SyncObjects on the same listener thread can unblock each
737 TEST_F(IPCSyncChannelTest
, Multiple
) {
738 Multiple(false, false);
739 Multiple(false, true);
740 Multiple(true, false);
741 Multiple(true, true);
744 //------------------------------------------------------------------------------
746 // This class provides server side functionality to test the case where
747 // multiple sync channels are in use on the same thread on the client and
748 // nested calls are issued.
749 class QueuedReplyServer
: public Worker
{
751 QueuedReplyServer(base::Thread
* listener_thread
,
752 const std::string
& channel_name
,
753 const std::string
& reply_text
)
754 : Worker(channel_name
, Channel::MODE_SERVER
),
755 reply_text_(reply_text
) {
756 Worker::OverrideThread(listener_thread
);
759 void OnNestedTestMsg(Message
* reply_msg
) override
{
760 VLOG(1) << __FUNCTION__
<< " Sending reply: " << reply_text_
;
761 SyncChannelNestedTestMsg_String::WriteReplyParams(reply_msg
, reply_text_
);
767 std::string reply_text_
;
770 // The QueuedReplyClient class provides functionality to test the case where
771 // multiple sync channels are in use on the same thread and they make nested
772 // sync calls, i.e. while the first channel waits for a response it makes a
773 // sync call on another channel.
774 // The callstack should unwind correctly, i.e. the outermost call should
775 // complete first, and so on.
776 class QueuedReplyClient
: public Worker
{
778 QueuedReplyClient(base::Thread
* listener_thread
,
779 const std::string
& channel_name
,
780 const std::string
& expected_text
,
781 bool pump_during_send
)
782 : Worker(channel_name
, Channel::MODE_CLIENT
),
783 pump_during_send_(pump_during_send
),
784 expected_text_(expected_text
) {
785 Worker::OverrideThread(listener_thread
);
788 void Run() override
{
789 std::string response
;
790 SyncMessage
* msg
= new SyncChannelNestedTestMsg_String(&response
);
791 if (pump_during_send_
)
792 msg
->EnableMessagePumping();
793 bool result
= Send(msg
);
795 DCHECK_EQ(response
, expected_text_
);
797 VLOG(1) << __FUNCTION__
<< " Received reply: " << response
;
802 bool pump_during_send_
;
803 std::string expected_text_
;
806 void QueuedReply(bool client_pump
) {
807 std::vector
<Worker
*> workers
;
809 // A shared worker thread for servers
810 base::Thread
server_worker_thread("QueuedReply_ServerListener");
811 ASSERT_TRUE(server_worker_thread
.Start());
813 base::Thread
client_worker_thread("QueuedReply_ClientListener");
814 ASSERT_TRUE(client_worker_thread
.Start());
818 worker
= new QueuedReplyServer(&server_worker_thread
,
819 "QueuedReply_Server1",
820 "Got first message");
821 workers
.push_back(worker
);
823 worker
= new QueuedReplyServer(&server_worker_thread
,
824 "QueuedReply_Server2",
825 "Got second message");
826 workers
.push_back(worker
);
828 worker
= new QueuedReplyClient(&client_worker_thread
,
829 "QueuedReply_Server1",
832 workers
.push_back(worker
);
834 worker
= new QueuedReplyClient(&client_worker_thread
,
835 "QueuedReply_Server2",
836 "Got second message",
838 workers
.push_back(worker
);
843 // While a blocking send is in progress, the listener thread might answer other
844 // synchronous messages. This tests that if during the response to another
845 // message the reply to the original messages comes, it is queued up correctly
846 // and the original Send is unblocked later.
847 // We also test that the send call stacks unwind correctly when the channel
848 // pumps messages while waiting for a response.
849 TEST_F(IPCSyncChannelTest
, QueuedReply
) {
854 //------------------------------------------------------------------------------
856 class ChattyClient
: public Worker
{
859 Worker(Channel::MODE_CLIENT
, "chatty_client") { }
861 void OnAnswer(int* answer
) override
{
862 // The PostMessage limit is 10k. Send 20% more than that.
863 const int kMessageLimit
= 10000;
864 const int kMessagesToSend
= kMessageLimit
* 120 / 100;
865 for (int i
= 0; i
< kMessagesToSend
; ++i
) {
866 if (!SendDouble(false, true))
874 void ChattyServer(bool pump_during_send
) {
875 std::vector
<Worker
*> workers
;
876 workers
.push_back(new UnblockServer(pump_during_send
, false));
877 workers
.push_back(new ChattyClient());
881 #if defined(OS_ANDROID)
883 #define MAYBE_ChattyServer DISABLED_ChattyServer
885 #define MAYBE_ChattyServer ChattyServer
887 // Tests http://b/1093251 - that sending lots of sync messages while
888 // the receiver is waiting for a sync reply does not overflow the PostMessage
890 TEST_F(IPCSyncChannelTest
, MAYBE_ChattyServer
) {
895 //------------------------------------------------------------------------------
897 void NestedCallback(Worker
* server
) {
898 // Sleep a bit so that we wake up after the reply has been received.
899 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(250));
900 server
->SendAnswerToLife(true, true);
903 bool timeout_occurred
= false;
905 void TimeoutCallback() {
906 timeout_occurred
= true;
909 class DoneEventRaceServer
: public Worker
{
911 DoneEventRaceServer()
912 : Worker(Channel::MODE_SERVER
, "done_event_race_server") { }
914 void Run() override
{
915 base::ThreadTaskRunnerHandle::Get()->PostTask(
916 FROM_HERE
, base::Bind(&NestedCallback
, this));
917 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
918 FROM_HERE
, base::Bind(&TimeoutCallback
),
919 base::TimeDelta::FromSeconds(9));
920 // Even though we have a timeout on the Send, it will succeed since for this
921 // bug, the reply message comes back and is deserialized, however the done
922 // event wasn't set. So we indirectly use the timeout task to notice if a
924 SendAnswerToLife(true, true);
925 DCHECK(!timeout_occurred
);
930 #if defined(OS_ANDROID)
931 #define MAYBE_DoneEventRace DISABLED_DoneEventRace
933 #define MAYBE_DoneEventRace DoneEventRace
935 // Tests http://b/1474092 - that if after the done_event is set but before
936 // OnObjectSignaled is called another message is sent out, then after its
937 // reply comes back OnObjectSignaled will be called for the first message.
938 TEST_F(IPCSyncChannelTest
, MAYBE_DoneEventRace
) {
939 std::vector
<Worker
*> workers
;
940 workers
.push_back(new DoneEventRaceServer());
941 workers
.push_back(new SimpleClient());
945 //------------------------------------------------------------------------------
947 class TestSyncMessageFilter
: public SyncMessageFilter
{
949 TestSyncMessageFilter(
950 base::WaitableEvent
* shutdown_event
,
952 scoped_refptr
<base::SingleThreadTaskRunner
> task_runner
)
953 : SyncMessageFilter(shutdown_event
),
955 task_runner_(task_runner
) {}
957 void OnFilterAdded(Sender
* sender
) override
{
958 SyncMessageFilter::OnFilterAdded(sender
);
959 task_runner_
->PostTask(
961 base::Bind(&TestSyncMessageFilter::SendMessageOnHelperThread
, this));
964 void SendMessageOnHelperThread() {
966 bool result
= Send(new SyncChannelTestMsg_AnswerToLife(&answer
));
968 DCHECK_EQ(answer
, 42);
974 ~TestSyncMessageFilter() override
{}
977 scoped_refptr
<base::SingleThreadTaskRunner
> task_runner_
;
980 class SyncMessageFilterServer
: public Worker
{
982 SyncMessageFilterServer()
983 : Worker(Channel::MODE_SERVER
, "sync_message_filter_server"),
984 thread_("helper_thread") {
985 base::Thread::Options options
;
986 options
.message_loop_type
= base::MessageLoop::TYPE_DEFAULT
;
987 thread_
.StartWithOptions(options
);
988 filter_
= new TestSyncMessageFilter(shutdown_event(), this,
989 thread_
.task_runner());
992 void Run() override
{
993 channel()->AddFilter(filter_
.get());
996 base::Thread thread_
;
997 scoped_refptr
<TestSyncMessageFilter
> filter_
;
1000 // This class provides functionality to test the case that a Send on the sync
1001 // channel does not crash after the channel has been closed.
1002 class ServerSendAfterClose
: public Worker
{
1004 ServerSendAfterClose()
1005 : Worker(Channel::MODE_SERVER
, "simpler_server"),
1006 send_result_(true) {
1010 ListenerThread()->task_runner()->PostTask(
1011 FROM_HERE
, base::Bind(base::IgnoreResult(&ServerSendAfterClose::Send
),
1012 this, new SyncChannelTestMsg_NoArgs
));
1016 bool send_result() const {
1017 return send_result_
;
1021 void Run() override
{
1026 bool Send(Message
* msg
) override
{
1027 send_result_
= Worker::Send(msg
);
1029 return send_result_
;
1035 // Tests basic synchronous call
1036 TEST_F(IPCSyncChannelTest
, SyncMessageFilter
) {
1037 std::vector
<Worker
*> workers
;
1038 workers
.push_back(new SyncMessageFilterServer());
1039 workers
.push_back(new SimpleClient());
1043 // Test the case when the channel is closed and a Send is attempted after that.
1044 TEST_F(IPCSyncChannelTest
, SendAfterClose
) {
1045 ServerSendAfterClose server
;
1048 server
.done_event()->Wait();
1049 server
.done_event()->Reset();
1052 server
.done_event()->Wait();
1054 EXPECT_FALSE(server
.send_result());
1059 //------------------------------------------------------------------------------
1061 class RestrictedDispatchServer
: public Worker
{
1063 RestrictedDispatchServer(WaitableEvent
* sent_ping_event
,
1064 WaitableEvent
* wait_event
)
1065 : Worker("restricted_channel", Channel::MODE_SERVER
),
1066 sent_ping_event_(sent_ping_event
),
1067 wait_event_(wait_event
) { }
1069 void OnDoPing(int ping
) {
1070 // Send an asynchronous message that unblocks the caller.
1071 Message
* msg
= new SyncChannelTestMsg_Ping(ping
);
1072 msg
->set_unblock(true);
1074 // Signal the event after the message has been sent on the channel, on the
1076 ipc_thread().task_runner()->PostTask(
1077 FROM_HERE
, base::Bind(&RestrictedDispatchServer::OnPingSent
, this));
1080 void OnPingTTL(int ping
, int* out
) {
1082 wait_event_
->Wait();
1085 base::Thread
* ListenerThread() { return Worker::ListenerThread(); }
1088 bool OnMessageReceived(const Message
& message
) override
{
1089 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchServer
, message
)
1090 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs
, OnNoArgs
)
1091 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_PingTTL
, OnPingTTL
)
1092 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done
, Done
)
1093 IPC_END_MESSAGE_MAP()
1098 sent_ping_event_
->Signal();
1102 WaitableEvent
* sent_ping_event_
;
1103 WaitableEvent
* wait_event_
;
1106 class NonRestrictedDispatchServer
: public Worker
{
1108 NonRestrictedDispatchServer(WaitableEvent
* signal_event
)
1109 : Worker("non_restricted_channel", Channel::MODE_SERVER
),
1110 signal_event_(signal_event
) {}
1112 base::Thread
* ListenerThread() { return Worker::ListenerThread(); }
1114 void OnDoPingTTL(int ping
) {
1116 Send(new SyncChannelTestMsg_PingTTL(ping
, &value
));
1117 signal_event_
->Signal();
1121 bool OnMessageReceived(const Message
& message
) override
{
1122 IPC_BEGIN_MESSAGE_MAP(NonRestrictedDispatchServer
, message
)
1123 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs
, OnNoArgs
)
1124 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done
, Done
)
1125 IPC_END_MESSAGE_MAP()
1130 WaitableEvent
* signal_event_
;
1133 class RestrictedDispatchClient
: public Worker
{
1135 RestrictedDispatchClient(WaitableEvent
* sent_ping_event
,
1136 RestrictedDispatchServer
* server
,
1137 NonRestrictedDispatchServer
* server2
,
1139 : Worker("restricted_channel", Channel::MODE_CLIENT
),
1144 sent_ping_event_(sent_ping_event
) {}
1146 void Run() override
{
1147 // Incoming messages from our channel should only be dispatched when we
1148 // send a message on that same channel.
1149 channel()->SetRestrictDispatchChannelGroup(1);
1151 server_
->ListenerThread()->task_runner()->PostTask(
1152 FROM_HERE
, base::Bind(&RestrictedDispatchServer::OnDoPing
, server_
, 1));
1153 sent_ping_event_
->Wait();
1154 Send(new SyncChannelTestMsg_NoArgs
);
1158 LOG(ERROR
) << "Send failed to dispatch incoming message on same channel";
1160 non_restricted_channel_
= SyncChannel::Create(
1161 "non_restricted_channel", IPC::Channel::MODE_CLIENT
, this,
1162 ipc_thread().task_runner().get(), true, shutdown_event(), nullptr);
1164 server_
->ListenerThread()->task_runner()->PostTask(
1165 FROM_HERE
, base::Bind(&RestrictedDispatchServer::OnDoPing
, server_
, 2));
1166 sent_ping_event_
->Wait();
1167 // Check that the incoming message is *not* dispatched when sending on the
1168 // non restricted channel.
1169 // TODO(piman): there is a possibility of a false positive race condition
1170 // here, if the message that was posted on the server-side end of the pipe
1171 // is not visible yet on the client side, but I don't know how to solve this
1172 // without hooking into the internals of SyncChannel. I haven't seen it in
1173 // practice (i.e. not setting SetRestrictDispatchToSameChannel does cause
1174 // the following to fail).
1175 non_restricted_channel_
->Send(new SyncChannelTestMsg_NoArgs
);
1179 LOG(ERROR
) << "Send dispatched message from restricted channel";
1181 Send(new SyncChannelTestMsg_NoArgs
);
1185 LOG(ERROR
) << "Send failed to dispatch incoming message on same channel";
1187 // Check that the incoming message on the non-restricted channel is
1188 // dispatched when sending on the restricted channel.
1189 server2_
->ListenerThread()->task_runner()->PostTask(
1191 base::Bind(&NonRestrictedDispatchServer::OnDoPingTTL
, server2_
, 3));
1193 Send(new SyncChannelTestMsg_PingTTL(4, &value
));
1194 if (ping_
== 3 && value
== 4)
1197 LOG(ERROR
) << "Send failed to dispatch message from unrestricted channel";
1199 non_restricted_channel_
->Send(new SyncChannelTestMsg_Done
);
1200 non_restricted_channel_
.reset();
1201 Send(new SyncChannelTestMsg_Done
);
1206 bool OnMessageReceived(const Message
& message
) override
{
1207 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchClient
, message
)
1208 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Ping
, OnPing
)
1209 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_PingTTL
, OnPingTTL
)
1210 IPC_END_MESSAGE_MAP()
1214 void OnPing(int ping
) {
1218 void OnPingTTL(int ping
, IPC::Message
* reply
) {
1220 // This message comes from the NonRestrictedDispatchServer, we have to send
1221 // the reply back manually.
1222 SyncChannelTestMsg_PingTTL::WriteReplyParams(reply
, ping
);
1223 non_restricted_channel_
->Send(reply
);
1227 RestrictedDispatchServer
* server_
;
1228 NonRestrictedDispatchServer
* server2_
;
1230 WaitableEvent
* sent_ping_event_
;
1231 scoped_ptr
<SyncChannel
> non_restricted_channel_
;
1234 TEST_F(IPCSyncChannelTest
, RestrictedDispatch
) {
1235 WaitableEvent
sent_ping_event(false, false);
1236 WaitableEvent
wait_event(false, false);
1237 RestrictedDispatchServer
* server
=
1238 new RestrictedDispatchServer(&sent_ping_event
, &wait_event
);
1239 NonRestrictedDispatchServer
* server2
=
1240 new NonRestrictedDispatchServer(&wait_event
);
1243 std::vector
<Worker
*> workers
;
1244 workers
.push_back(server
);
1245 workers
.push_back(server2
);
1246 workers
.push_back(new RestrictedDispatchClient(
1247 &sent_ping_event
, server
, server2
, &success
));
1249 EXPECT_EQ(4, success
);
1252 //------------------------------------------------------------------------------
1254 // This test case inspired by crbug.com/108491
1255 // We create two servers that use the same ListenerThread but have
1256 // SetRestrictDispatchToSameChannel set to true.
1257 // We create clients, then use some specific WaitableEvent wait/signalling to
1258 // ensure that messages get dispatched in a way that causes a deadlock due to
1259 // a nested dispatch and an eligible message in a higher-level dispatch's
1260 // delayed_queue. Specifically, we start with client1 about so send an
1261 // unblocking message to server1, while the shared listener thread for the
1262 // servers server1 and server2 is about to send a non-unblocking message to
1263 // client1. At the same time, client2 will be about to send an unblocking
1264 // message to server2. Server1 will handle the client1->server1 message by
1265 // telling server2 to send a non-unblocking message to client2.
1266 // What should happen is that the send to server2 should find the pending,
1267 // same-context client2->server2 message to dispatch, causing client2 to
1268 // unblock then handle the server2->client2 message, so that the shared
1269 // servers' listener thread can then respond to the client1->server1 message.
1270 // Then client1 can handle the non-unblocking server1->client1 message.
1271 // The old code would end up in a state where the server2->client2 message is
1272 // sent, but the client2->server2 message (which is eligible for dispatch, and
1273 // which is what client2 is waiting for) is stashed in a local delayed_queue
1274 // that has server1's channel context, causing a deadlock.
1275 // WaitableEvents in the events array are used to:
1276 // event 0: indicate to client1 that server listener is in OnDoServerTask
1277 // event 1: indicate to client1 that client2 listener is in OnDoClient2Task
1278 // event 2: indicate to server1 that client2 listener is in OnDoClient2Task
1279 // event 3: indicate to client2 that server listener is in OnDoServerTask
1281 class RestrictedDispatchDeadlockServer
: public Worker
{
1283 RestrictedDispatchDeadlockServer(int server_num
,
1284 WaitableEvent
* server_ready_event
,
1285 WaitableEvent
** events
,
1286 RestrictedDispatchDeadlockServer
* peer
)
1287 : Worker(server_num
== 1 ? "channel1" : "channel2", Channel::MODE_SERVER
),
1288 server_num_(server_num
),
1289 server_ready_event_(server_ready_event
),
1293 void OnDoServerTask() {
1294 events_
[3]->Signal();
1296 events_
[0]->Signal();
1297 SendMessageToClient();
1300 void Run() override
{
1301 channel()->SetRestrictDispatchChannelGroup(1);
1302 server_ready_event_
->Signal();
1305 base::Thread
* ListenerThread() { return Worker::ListenerThread(); }
1308 bool OnMessageReceived(const Message
& message
) override
{
1309 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchDeadlockServer
, message
)
1310 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs
, OnNoArgs
)
1311 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done
, Done
)
1312 IPC_END_MESSAGE_MAP()
1317 if (server_num_
== 1) {
1318 DCHECK(peer_
!= NULL
);
1319 peer_
->SendMessageToClient();
1323 void SendMessageToClient() {
1324 Message
* msg
= new SyncChannelTestMsg_NoArgs
;
1325 msg
->set_unblock(false);
1326 DCHECK(!msg
->should_unblock());
1331 WaitableEvent
* server_ready_event_
;
1332 WaitableEvent
** events_
;
1333 RestrictedDispatchDeadlockServer
* peer_
;
1336 class RestrictedDispatchDeadlockClient2
: public Worker
{
1338 RestrictedDispatchDeadlockClient2(RestrictedDispatchDeadlockServer
* server
,
1339 WaitableEvent
* server_ready_event
,
1340 WaitableEvent
** events
)
1341 : Worker("channel2", Channel::MODE_CLIENT
),
1342 server_ready_event_(server_ready_event
),
1344 received_msg_(false),
1345 received_noarg_reply_(false),
1346 done_issued_(false) {}
1348 void Run() override
{
1349 server_ready_event_
->Wait();
1352 void OnDoClient2Task() {
1354 events_
[1]->Signal();
1355 events_
[2]->Signal();
1356 DCHECK(received_msg_
== false);
1358 Message
* message
= new SyncChannelTestMsg_NoArgs
;
1359 message
->set_unblock(true);
1361 received_noarg_reply_
= true;
1364 base::Thread
* ListenerThread() { return Worker::ListenerThread(); }
1366 bool OnMessageReceived(const Message
& message
) override
{
1367 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchDeadlockClient2
, message
)
1368 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs
, OnNoArgs
)
1369 IPC_END_MESSAGE_MAP()
1374 received_msg_
= true;
1378 void PossiblyDone() {
1379 if (received_noarg_reply_
&& received_msg_
) {
1380 DCHECK(done_issued_
== false);
1381 done_issued_
= true;
1382 Send(new SyncChannelTestMsg_Done
);
1387 WaitableEvent
* server_ready_event_
;
1388 WaitableEvent
** events_
;
1390 bool received_noarg_reply_
;
1394 class RestrictedDispatchDeadlockClient1
: public Worker
{
1396 RestrictedDispatchDeadlockClient1(RestrictedDispatchDeadlockServer
* server
,
1397 RestrictedDispatchDeadlockClient2
* peer
,
1398 WaitableEvent
* server_ready_event
,
1399 WaitableEvent
** events
)
1400 : Worker("channel1", Channel::MODE_CLIENT
),
1403 server_ready_event_(server_ready_event
),
1405 received_msg_(false),
1406 received_noarg_reply_(false),
1407 done_issued_(false) {}
1409 void Run() override
{
1410 server_ready_event_
->Wait();
1411 server_
->ListenerThread()->task_runner()->PostTask(
1413 base::Bind(&RestrictedDispatchDeadlockServer::OnDoServerTask
, server_
));
1414 peer_
->ListenerThread()->task_runner()->PostTask(
1416 base::Bind(&RestrictedDispatchDeadlockClient2::OnDoClient2Task
, peer_
));
1419 DCHECK(received_msg_
== false);
1421 Message
* message
= new SyncChannelTestMsg_NoArgs
;
1422 message
->set_unblock(true);
1424 received_noarg_reply_
= true;
1429 bool OnMessageReceived(const Message
& message
) override
{
1430 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchDeadlockClient1
, message
)
1431 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs
, OnNoArgs
)
1432 IPC_END_MESSAGE_MAP()
1437 received_msg_
= true;
1441 void PossiblyDone() {
1442 if (received_noarg_reply_
&& received_msg_
) {
1443 DCHECK(done_issued_
== false);
1444 done_issued_
= true;
1445 Send(new SyncChannelTestMsg_Done
);
1450 RestrictedDispatchDeadlockServer
* server_
;
1451 RestrictedDispatchDeadlockClient2
* peer_
;
1452 WaitableEvent
* server_ready_event_
;
1453 WaitableEvent
** events_
;
1455 bool received_noarg_reply_
;
1459 TEST_F(IPCSyncChannelTest
, RestrictedDispatchDeadlock
) {
1460 std::vector
<Worker
*> workers
;
1462 // A shared worker thread so that server1 and server2 run on one thread.
1463 base::Thread
worker_thread("RestrictedDispatchDeadlock");
1464 ASSERT_TRUE(worker_thread
.Start());
1466 WaitableEvent
server1_ready(false, false);
1467 WaitableEvent
server2_ready(false, false);
1469 WaitableEvent
event0(false, false);
1470 WaitableEvent
event1(false, false);
1471 WaitableEvent
event2(false, false);
1472 WaitableEvent
event3(false, false);
1473 WaitableEvent
* events
[4] = {&event0
, &event1
, &event2
, &event3
};
1475 RestrictedDispatchDeadlockServer
* server1
;
1476 RestrictedDispatchDeadlockServer
* server2
;
1477 RestrictedDispatchDeadlockClient1
* client1
;
1478 RestrictedDispatchDeadlockClient2
* client2
;
1480 server2
= new RestrictedDispatchDeadlockServer(2, &server2_ready
, events
,
1482 server2
->OverrideThread(&worker_thread
);
1483 workers
.push_back(server2
);
1485 client2
= new RestrictedDispatchDeadlockClient2(server2
, &server2_ready
,
1487 workers
.push_back(client2
);
1489 server1
= new RestrictedDispatchDeadlockServer(1, &server1_ready
, events
,
1491 server1
->OverrideThread(&worker_thread
);
1492 workers
.push_back(server1
);
1494 client1
= new RestrictedDispatchDeadlockClient1(server1
, client2
,
1495 &server1_ready
, events
);
1496 workers
.push_back(client1
);
1501 //------------------------------------------------------------------------------
1503 // This test case inspired by crbug.com/120530
1504 // We create 4 workers that pipe to each other W1->W2->W3->W4->W1 then we send a
1505 // message that recurses through 3, 4 or 5 steps to make sure, say, W1 can
1506 // re-enter when called from W4 while it's sending a message to W2.
1507 // The first worker drives the whole test so it must be treated specially.
1509 class RestrictedDispatchPipeWorker
: public Worker
{
1511 RestrictedDispatchPipeWorker(
1512 const std::string
&channel1
,
1513 WaitableEvent
* event1
,
1514 const std::string
&channel2
,
1515 WaitableEvent
* event2
,
1518 : Worker(channel1
, Channel::MODE_SERVER
),
1521 other_channel_name_(channel2
),
1526 void OnPingTTL(int ping
, int* ret
) {
1530 other_channel_
->Send(new SyncChannelTestMsg_PingTTL(ping
- 1, ret
));
1537 other_channel_
->Send(new SyncChannelTestMsg_Done
);
1538 other_channel_
.reset();
1542 void Run() override
{
1543 channel()->SetRestrictDispatchChannelGroup(group_
);
1547 other_channel_
= SyncChannel::Create(
1548 other_channel_name_
, IPC::Channel::MODE_CLIENT
, this,
1549 ipc_thread().task_runner().get(), true, shutdown_event(), nullptr);
1550 other_channel_
->SetRestrictDispatchChannelGroup(group_
);
1557 OnPingTTL(3, &value
);
1558 *success_
+= (value
== 3);
1559 OnPingTTL(4, &value
);
1560 *success_
+= (value
== 4);
1561 OnPingTTL(5, &value
);
1562 *success_
+= (value
== 5);
1563 other_channel_
->Send(new SyncChannelTestMsg_Done
);
1564 other_channel_
.reset();
1568 bool is_first() { return !!success_
; }
1571 bool OnMessageReceived(const Message
& message
) override
{
1572 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchPipeWorker
, message
)
1573 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_PingTTL
, OnPingTTL
)
1574 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done
, OnDone
)
1575 IPC_END_MESSAGE_MAP()
1579 scoped_ptr
<SyncChannel
> other_channel_
;
1580 WaitableEvent
* event1_
;
1581 WaitableEvent
* event2_
;
1582 std::string other_channel_name_
;
1587 #if defined(OS_ANDROID)
1588 #define MAYBE_RestrictedDispatch4WayDeadlock \
1589 DISABLED_RestrictedDispatch4WayDeadlock
1591 #define MAYBE_RestrictedDispatch4WayDeadlock RestrictedDispatch4WayDeadlock
1593 TEST_F(IPCSyncChannelTest
, MAYBE_RestrictedDispatch4WayDeadlock
) {
1595 std::vector
<Worker
*> workers
;
1596 WaitableEvent
event0(true, false);
1597 WaitableEvent
event1(true, false);
1598 WaitableEvent
event2(true, false);
1599 WaitableEvent
event3(true, false);
1600 workers
.push_back(new RestrictedDispatchPipeWorker(
1601 "channel0", &event0
, "channel1", &event1
, 1, &success
));
1602 workers
.push_back(new RestrictedDispatchPipeWorker(
1603 "channel1", &event1
, "channel2", &event2
, 2, NULL
));
1604 workers
.push_back(new RestrictedDispatchPipeWorker(
1605 "channel2", &event2
, "channel3", &event3
, 3, NULL
));
1606 workers
.push_back(new RestrictedDispatchPipeWorker(
1607 "channel3", &event3
, "channel0", &event0
, 4, NULL
));
1609 EXPECT_EQ(3, success
);
1612 //------------------------------------------------------------------------------
1614 // This test case inspired by crbug.com/122443
1615 // We want to make sure a reply message with the unblock flag set correctly
1616 // behaves as a reply, not a regular message.
1617 // We have 3 workers. Server1 will send a message to Server2 (which will block),
1618 // during which it will dispatch a message comming from Client, at which point
1619 // it will send another message to Server2. While sending that second message it
1620 // will receive a reply from Server1 with the unblock flag.
1622 class ReentrantReplyServer1
: public Worker
{
1624 ReentrantReplyServer1(WaitableEvent
* server_ready
)
1625 : Worker("reentrant_reply1", Channel::MODE_SERVER
),
1626 server_ready_(server_ready
) { }
1628 void Run() override
{
1629 server2_channel_
= SyncChannel::Create(
1630 "reentrant_reply2", IPC::Channel::MODE_CLIENT
, this,
1631 ipc_thread().task_runner().get(), true, shutdown_event(), nullptr);
1632 server_ready_
->Signal();
1633 Message
* msg
= new SyncChannelTestMsg_Reentrant1();
1634 server2_channel_
->Send(msg
);
1635 server2_channel_
.reset();
1640 bool OnMessageReceived(const Message
& message
) override
{
1641 IPC_BEGIN_MESSAGE_MAP(ReentrantReplyServer1
, message
)
1642 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Reentrant2
, OnReentrant2
)
1643 IPC_REPLY_HANDLER(OnReply
)
1644 IPC_END_MESSAGE_MAP()
1648 void OnReentrant2() {
1649 Message
* msg
= new SyncChannelTestMsg_Reentrant3();
1650 server2_channel_
->Send(msg
);
1653 void OnReply(const Message
& message
) {
1654 // If we get here, the Send() will never receive the reply (thus would
1655 // hang), so abort instead.
1656 LOG(FATAL
) << "Reply message was dispatched";
1659 WaitableEvent
* server_ready_
;
1660 scoped_ptr
<SyncChannel
> server2_channel_
;
1663 class ReentrantReplyServer2
: public Worker
{
1665 ReentrantReplyServer2()
1666 : Worker("reentrant_reply2", Channel::MODE_SERVER
),
1670 bool OnMessageReceived(const Message
& message
) override
{
1671 IPC_BEGIN_MESSAGE_MAP(ReentrantReplyServer2
, message
)
1672 IPC_MESSAGE_HANDLER_DELAY_REPLY(
1673 SyncChannelTestMsg_Reentrant1
, OnReentrant1
)
1674 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Reentrant3
, OnReentrant3
)
1675 IPC_END_MESSAGE_MAP()
1679 void OnReentrant1(Message
* reply
) {
1684 void OnReentrant3() {
1686 Message
* reply
= reply_
;
1688 reply
->set_unblock(true);
1696 class ReentrantReplyClient
: public Worker
{
1698 ReentrantReplyClient(WaitableEvent
* server_ready
)
1699 : Worker("reentrant_reply1", Channel::MODE_CLIENT
),
1700 server_ready_(server_ready
) { }
1702 void Run() override
{
1703 server_ready_
->Wait();
1704 Send(new SyncChannelTestMsg_Reentrant2());
1709 WaitableEvent
* server_ready_
;
1712 TEST_F(IPCSyncChannelTest
, ReentrantReply
) {
1713 std::vector
<Worker
*> workers
;
1714 WaitableEvent
server_ready(false, false);
1715 workers
.push_back(new ReentrantReplyServer2());
1716 workers
.push_back(new ReentrantReplyServer1(&server_ready
));
1717 workers
.push_back(new ReentrantReplyClient(&server_ready
));
1721 //------------------------------------------------------------------------------
1723 // Generate a validated channel ID using Channel::GenerateVerifiedChannelID().
1725 class VerifiedServer
: public Worker
{
1727 VerifiedServer(base::Thread
* listener_thread
,
1728 const std::string
& channel_name
,
1729 const std::string
& reply_text
)
1730 : Worker(channel_name
, Channel::MODE_SERVER
),
1731 reply_text_(reply_text
) {
1732 Worker::OverrideThread(listener_thread
);
1735 void OnNestedTestMsg(Message
* reply_msg
) override
{
1736 VLOG(1) << __FUNCTION__
<< " Sending reply: " << reply_text_
;
1737 SyncChannelNestedTestMsg_String::WriteReplyParams(reply_msg
, reply_text_
);
1739 ASSERT_EQ(channel()->GetPeerPID(), base::GetCurrentProcId());
1744 std::string reply_text_
;
1747 class VerifiedClient
: public Worker
{
1749 VerifiedClient(base::Thread
* listener_thread
,
1750 const std::string
& channel_name
,
1751 const std::string
& expected_text
)
1752 : Worker(channel_name
, Channel::MODE_CLIENT
),
1753 expected_text_(expected_text
) {
1754 Worker::OverrideThread(listener_thread
);
1757 void Run() override
{
1758 std::string response
;
1759 SyncMessage
* msg
= new SyncChannelNestedTestMsg_String(&response
);
1760 bool result
= Send(msg
);
1762 DCHECK_EQ(response
, expected_text_
);
1763 // expected_text_ is only used in the above DCHECK. This line suppresses the
1764 // "unused private field" warning in release builds.
1765 (void)expected_text_
;
1767 VLOG(1) << __FUNCTION__
<< " Received reply: " << response
;
1768 ASSERT_EQ(channel()->GetPeerPID(), base::GetCurrentProcId());
1773 std::string expected_text_
;
1777 std::vector
<Worker
*> workers
;
1779 // A shared worker thread for servers
1780 base::Thread
server_worker_thread("Verified_ServerListener");
1781 ASSERT_TRUE(server_worker_thread
.Start());
1783 base::Thread
client_worker_thread("Verified_ClientListener");
1784 ASSERT_TRUE(client_worker_thread
.Start());
1786 std::string channel_id
= Channel::GenerateVerifiedChannelID("Verified");
1789 worker
= new VerifiedServer(&server_worker_thread
,
1791 "Got first message");
1792 workers
.push_back(worker
);
1794 worker
= new VerifiedClient(&client_worker_thread
,
1796 "Got first message");
1797 workers
.push_back(worker
);
1802 // Windows needs to send an out-of-band secret to verify the client end of the
1803 // channel. Test that we still connect correctly in that case.
1804 TEST_F(IPCSyncChannelTest
, Verified
) {