xref: /aosp_15_r20/external/libchrome/ipc/ipc_sync_channel_unittest.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_sync_channel.h"
6*635a8641SAndroid Build Coastguard Worker 
7*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
8*635a8641SAndroid Build Coastguard Worker 
9*635a8641SAndroid Build Coastguard Worker #include <memory>
10*635a8641SAndroid Build Coastguard Worker #include <string>
11*635a8641SAndroid Build Coastguard Worker #include <utility>
12*635a8641SAndroid Build Coastguard Worker #include <vector>
13*635a8641SAndroid Build Coastguard Worker 
14*635a8641SAndroid Build Coastguard Worker #include "base/bind.h"
15*635a8641SAndroid Build Coastguard Worker #include "base/location.h"
16*635a8641SAndroid Build Coastguard Worker #include "base/logging.h"
17*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
18*635a8641SAndroid Build Coastguard Worker #include "base/message_loop/message_loop.h"
19*635a8641SAndroid Build Coastguard Worker #include "base/process/process_handle.h"
20*635a8641SAndroid Build Coastguard Worker #include "base/run_loop.h"
21*635a8641SAndroid Build Coastguard Worker #include "base/single_thread_task_runner.h"
22*635a8641SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
23*635a8641SAndroid Build Coastguard Worker #include "base/synchronization/waitable_event.h"
24*635a8641SAndroid Build Coastguard Worker #include "base/threading/platform_thread.h"
25*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread.h"
26*635a8641SAndroid Build Coastguard Worker #include "base/threading/thread_task_runner_handle.h"
27*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
28*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_listener.h"
29*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_message.h"
30*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_sender.h"
31*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_sync_message_filter.h"
32*635a8641SAndroid Build Coastguard Worker #include "ipc/ipc_sync_message_unittest.h"
33*635a8641SAndroid Build Coastguard Worker #include "mojo/public/cpp/system/message_pipe.h"
34*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
35*635a8641SAndroid Build Coastguard Worker 
36*635a8641SAndroid Build Coastguard Worker using base::WaitableEvent;
37*635a8641SAndroid Build Coastguard Worker 
38*635a8641SAndroid Build Coastguard Worker namespace IPC {
39*635a8641SAndroid Build Coastguard Worker namespace {
40*635a8641SAndroid Build Coastguard Worker 
41*635a8641SAndroid Build Coastguard Worker // Base class for a "process" with listener and IPC threads.
42*635a8641SAndroid Build Coastguard Worker class Worker : public Listener, public Sender {
43*635a8641SAndroid Build Coastguard Worker  public:
44*635a8641SAndroid Build Coastguard Worker   // Will create a channel without a name.
Worker(Channel::Mode mode,const std::string & thread_name,mojo::ScopedMessagePipeHandle channel_handle)45*635a8641SAndroid Build Coastguard Worker   Worker(Channel::Mode mode,
46*635a8641SAndroid Build Coastguard Worker          const std::string& thread_name,
47*635a8641SAndroid Build Coastguard Worker          mojo::ScopedMessagePipeHandle channel_handle)
48*635a8641SAndroid Build Coastguard Worker       : done_(
49*635a8641SAndroid Build Coastguard Worker             new WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC,
50*635a8641SAndroid Build Coastguard Worker                               base::WaitableEvent::InitialState::NOT_SIGNALED)),
51*635a8641SAndroid Build Coastguard Worker         channel_created_(
52*635a8641SAndroid Build Coastguard Worker             new WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC,
53*635a8641SAndroid Build Coastguard Worker                               base::WaitableEvent::InitialState::NOT_SIGNALED)),
54*635a8641SAndroid Build Coastguard Worker         channel_handle_(std::move(channel_handle)),
55*635a8641SAndroid Build Coastguard Worker         mode_(mode),
56*635a8641SAndroid Build Coastguard Worker         ipc_thread_((thread_name + "_ipc").c_str()),
57*635a8641SAndroid Build Coastguard Worker         listener_thread_((thread_name + "_listener").c_str()),
58*635a8641SAndroid Build Coastguard Worker         overrided_thread_(NULL),
59*635a8641SAndroid Build Coastguard Worker         shutdown_event_(base::WaitableEvent::ResetPolicy::MANUAL,
60*635a8641SAndroid Build Coastguard Worker                         base::WaitableEvent::InitialState::NOT_SIGNALED),
61*635a8641SAndroid Build Coastguard Worker         is_shutdown_(false) {}
62*635a8641SAndroid Build Coastguard Worker 
63*635a8641SAndroid Build Coastguard Worker   // Will create a named channel and use this name for the threads' name.
Worker(mojo::ScopedMessagePipeHandle channel_handle,Channel::Mode mode)64*635a8641SAndroid Build Coastguard Worker   Worker(mojo::ScopedMessagePipeHandle channel_handle, Channel::Mode mode)
65*635a8641SAndroid Build Coastguard Worker       : done_(
66*635a8641SAndroid Build Coastguard Worker             new WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC,
67*635a8641SAndroid Build Coastguard Worker                               base::WaitableEvent::InitialState::NOT_SIGNALED)),
68*635a8641SAndroid Build Coastguard Worker         channel_created_(
69*635a8641SAndroid Build Coastguard Worker             new WaitableEvent(base::WaitableEvent::ResetPolicy::AUTOMATIC,
70*635a8641SAndroid Build Coastguard Worker                               base::WaitableEvent::InitialState::NOT_SIGNALED)),
71*635a8641SAndroid Build Coastguard Worker         channel_handle_(std::move(channel_handle)),
72*635a8641SAndroid Build Coastguard Worker         mode_(mode),
73*635a8641SAndroid Build Coastguard Worker         ipc_thread_("ipc thread"),
74*635a8641SAndroid Build Coastguard Worker         listener_thread_("listener thread"),
75*635a8641SAndroid Build Coastguard Worker         overrided_thread_(NULL),
76*635a8641SAndroid Build Coastguard Worker         shutdown_event_(base::WaitableEvent::ResetPolicy::MANUAL,
77*635a8641SAndroid Build Coastguard Worker                         base::WaitableEvent::InitialState::NOT_SIGNALED),
78*635a8641SAndroid Build Coastguard Worker         is_shutdown_(false) {}
79*635a8641SAndroid Build Coastguard Worker 
~Worker()80*635a8641SAndroid Build Coastguard Worker   ~Worker() override {
81*635a8641SAndroid Build Coastguard Worker     // Shutdown() must be called before destruction.
82*635a8641SAndroid Build Coastguard Worker     CHECK(is_shutdown_);
83*635a8641SAndroid Build Coastguard Worker   }
Send(Message * msg)84*635a8641SAndroid Build Coastguard Worker   bool Send(Message* msg) override { return channel_->Send(msg); }
WaitForChannelCreation()85*635a8641SAndroid Build Coastguard Worker   void WaitForChannelCreation() { channel_created_->Wait(); }
CloseChannel()86*635a8641SAndroid Build Coastguard Worker   void CloseChannel() {
87*635a8641SAndroid Build Coastguard Worker     DCHECK(ListenerThread()->task_runner()->BelongsToCurrentThread());
88*635a8641SAndroid Build Coastguard Worker     channel_->Close();
89*635a8641SAndroid Build Coastguard Worker   }
Start()90*635a8641SAndroid Build Coastguard Worker   void Start() {
91*635a8641SAndroid Build Coastguard Worker     StartThread(&listener_thread_, base::MessageLoop::TYPE_DEFAULT);
92*635a8641SAndroid Build Coastguard Worker     ListenerThread()->task_runner()->PostTask(
93*635a8641SAndroid Build Coastguard Worker         FROM_HERE, base::Bind(&Worker::OnStart, base::Unretained(this)));
94*635a8641SAndroid Build Coastguard Worker   }
Shutdown()95*635a8641SAndroid Build Coastguard Worker   void Shutdown() {
96*635a8641SAndroid Build Coastguard Worker     // The IPC thread needs to outlive SyncChannel. We can't do this in
97*635a8641SAndroid Build Coastguard Worker     // ~Worker(), since that'll reset the vtable pointer (to Worker's), which
98*635a8641SAndroid Build Coastguard Worker     // may result in a race conditions. See http://crbug.com/25841.
99*635a8641SAndroid Build Coastguard Worker     WaitableEvent listener_done(
100*635a8641SAndroid Build Coastguard Worker         base::WaitableEvent::ResetPolicy::AUTOMATIC,
101*635a8641SAndroid Build Coastguard Worker         base::WaitableEvent::InitialState::NOT_SIGNALED),
102*635a8641SAndroid Build Coastguard Worker         ipc_done(base::WaitableEvent::ResetPolicy::AUTOMATIC,
103*635a8641SAndroid Build Coastguard Worker                  base::WaitableEvent::InitialState::NOT_SIGNALED);
104*635a8641SAndroid Build Coastguard Worker     ListenerThread()->task_runner()->PostTask(
105*635a8641SAndroid Build Coastguard Worker         FROM_HERE,
106*635a8641SAndroid Build Coastguard Worker         base::Bind(&Worker::OnListenerThreadShutdown1, base::Unretained(this),
107*635a8641SAndroid Build Coastguard Worker                    &listener_done, &ipc_done));
108*635a8641SAndroid Build Coastguard Worker     listener_done.Wait();
109*635a8641SAndroid Build Coastguard Worker     ipc_done.Wait();
110*635a8641SAndroid Build Coastguard Worker     ipc_thread_.Stop();
111*635a8641SAndroid Build Coastguard Worker     listener_thread_.Stop();
112*635a8641SAndroid Build Coastguard Worker     is_shutdown_ = true;
113*635a8641SAndroid Build Coastguard Worker   }
OverrideThread(base::Thread * overrided_thread)114*635a8641SAndroid Build Coastguard Worker   void OverrideThread(base::Thread* overrided_thread) {
115*635a8641SAndroid Build Coastguard Worker     DCHECK(overrided_thread_ == NULL);
116*635a8641SAndroid Build Coastguard Worker     overrided_thread_ = overrided_thread;
117*635a8641SAndroid Build Coastguard Worker   }
SendAnswerToLife(bool pump,bool succeed)118*635a8641SAndroid Build Coastguard Worker   bool SendAnswerToLife(bool pump, bool succeed) {
119*635a8641SAndroid Build Coastguard Worker     int answer = 0;
120*635a8641SAndroid Build Coastguard Worker     SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer);
121*635a8641SAndroid Build Coastguard Worker     if (pump)
122*635a8641SAndroid Build Coastguard Worker       msg->EnableMessagePumping();
123*635a8641SAndroid Build Coastguard Worker     bool result = Send(msg);
124*635a8641SAndroid Build Coastguard Worker     DCHECK_EQ(result, succeed);
125*635a8641SAndroid Build Coastguard Worker     DCHECK_EQ(answer, (succeed ? 42 : 0));
126*635a8641SAndroid Build Coastguard Worker     return result;
127*635a8641SAndroid Build Coastguard Worker   }
SendDouble(bool pump,bool succeed)128*635a8641SAndroid Build Coastguard Worker   bool SendDouble(bool pump, bool succeed) {
129*635a8641SAndroid Build Coastguard Worker     int answer = 0;
130*635a8641SAndroid Build Coastguard Worker     SyncMessage* msg = new SyncChannelTestMsg_Double(5, &answer);
131*635a8641SAndroid Build Coastguard Worker     if (pump)
132*635a8641SAndroid Build Coastguard Worker       msg->EnableMessagePumping();
133*635a8641SAndroid Build Coastguard Worker     bool result = Send(msg);
134*635a8641SAndroid Build Coastguard Worker     DCHECK_EQ(result, succeed);
135*635a8641SAndroid Build Coastguard Worker     DCHECK_EQ(answer, (succeed ? 10 : 0));
136*635a8641SAndroid Build Coastguard Worker     return result;
137*635a8641SAndroid Build Coastguard Worker   }
TakeChannelHandle()138*635a8641SAndroid Build Coastguard Worker   mojo::MessagePipeHandle TakeChannelHandle() {
139*635a8641SAndroid Build Coastguard Worker     DCHECK(channel_handle_.is_valid());
140*635a8641SAndroid Build Coastguard Worker     return channel_handle_.release();
141*635a8641SAndroid Build Coastguard Worker   }
mode()142*635a8641SAndroid Build Coastguard Worker   Channel::Mode mode() { return mode_; }
done_event()143*635a8641SAndroid Build Coastguard Worker   WaitableEvent* done_event() { return done_.get(); }
shutdown_event()144*635a8641SAndroid Build Coastguard Worker   WaitableEvent* shutdown_event() { return &shutdown_event_; }
ResetChannel()145*635a8641SAndroid Build Coastguard Worker   void ResetChannel() { channel_.reset(); }
146*635a8641SAndroid Build Coastguard Worker   // Derived classes need to call this when they've completed their part of
147*635a8641SAndroid Build Coastguard Worker   // the test.
Done()148*635a8641SAndroid Build Coastguard Worker   void Done() { done_->Signal(); }
149*635a8641SAndroid Build Coastguard Worker 
150*635a8641SAndroid Build Coastguard Worker  protected:
channel()151*635a8641SAndroid Build Coastguard Worker   SyncChannel* channel() { return channel_.get(); }
152*635a8641SAndroid Build Coastguard Worker   // Functions for derived classes to implement if they wish.
Run()153*635a8641SAndroid Build Coastguard Worker   virtual void Run() { }
OnAnswer(int * answer)154*635a8641SAndroid Build Coastguard Worker   virtual void OnAnswer(int* answer) { NOTREACHED(); }
OnAnswerDelay(Message * reply_msg)155*635a8641SAndroid Build Coastguard Worker   virtual void OnAnswerDelay(Message* reply_msg) {
156*635a8641SAndroid Build Coastguard Worker     // The message handler map below can only take one entry for
157*635a8641SAndroid Build Coastguard Worker     // SyncChannelTestMsg_AnswerToLife, so since some classes want
158*635a8641SAndroid Build Coastguard Worker     // the normal version while other want the delayed reply, we
159*635a8641SAndroid Build Coastguard Worker     // call the normal version if the derived class didn't override
160*635a8641SAndroid Build Coastguard Worker     // this function.
161*635a8641SAndroid Build Coastguard Worker     int answer;
162*635a8641SAndroid Build Coastguard Worker     OnAnswer(&answer);
163*635a8641SAndroid Build Coastguard Worker     SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, answer);
164*635a8641SAndroid Build Coastguard Worker     Send(reply_msg);
165*635a8641SAndroid Build Coastguard Worker   }
OnDouble(int in,int * out)166*635a8641SAndroid Build Coastguard Worker   virtual void OnDouble(int in, int* out) { NOTREACHED(); }
OnDoubleDelay(int in,Message * reply_msg)167*635a8641SAndroid Build Coastguard Worker   virtual void OnDoubleDelay(int in, Message* reply_msg) {
168*635a8641SAndroid Build Coastguard Worker     int result;
169*635a8641SAndroid Build Coastguard Worker     OnDouble(in, &result);
170*635a8641SAndroid Build Coastguard Worker     SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, result);
171*635a8641SAndroid Build Coastguard Worker     Send(reply_msg);
172*635a8641SAndroid Build Coastguard Worker   }
173*635a8641SAndroid Build Coastguard Worker 
OnNestedTestMsg(Message * reply_msg)174*635a8641SAndroid Build Coastguard Worker   virtual void OnNestedTestMsg(Message* reply_msg) {
175*635a8641SAndroid Build Coastguard Worker     NOTREACHED();
176*635a8641SAndroid Build Coastguard Worker   }
177*635a8641SAndroid Build Coastguard Worker 
CreateChannel()178*635a8641SAndroid Build Coastguard Worker   virtual SyncChannel* CreateChannel() {
179*635a8641SAndroid Build Coastguard Worker     std::unique_ptr<SyncChannel> channel = SyncChannel::Create(
180*635a8641SAndroid Build Coastguard Worker         TakeChannelHandle(), mode_, this, ipc_thread_.task_runner(),
181*635a8641SAndroid Build Coastguard Worker         base::ThreadTaskRunnerHandle::Get(), true, &shutdown_event_);
182*635a8641SAndroid Build Coastguard Worker     return channel.release();
183*635a8641SAndroid Build Coastguard Worker   }
184*635a8641SAndroid Build Coastguard Worker 
ListenerThread()185*635a8641SAndroid Build Coastguard Worker   base::Thread* ListenerThread() {
186*635a8641SAndroid Build Coastguard Worker     return overrided_thread_ ? overrided_thread_ : &listener_thread_;
187*635a8641SAndroid Build Coastguard Worker   }
188*635a8641SAndroid Build Coastguard Worker 
ipc_thread() const189*635a8641SAndroid Build Coastguard Worker   const base::Thread& ipc_thread() const { return ipc_thread_; }
190*635a8641SAndroid Build Coastguard Worker 
191*635a8641SAndroid Build Coastguard Worker  private:
192*635a8641SAndroid Build Coastguard Worker   // Called on the listener thread to create the sync channel.
OnStart()193*635a8641SAndroid Build Coastguard Worker   void OnStart() {
194*635a8641SAndroid Build Coastguard Worker     // Link ipc_thread_, listener_thread_ and channel_ altogether.
195*635a8641SAndroid Build Coastguard Worker     StartThread(&ipc_thread_, base::MessageLoop::TYPE_IO);
196*635a8641SAndroid Build Coastguard Worker     channel_.reset(CreateChannel());
197*635a8641SAndroid Build Coastguard Worker     channel_created_->Signal();
198*635a8641SAndroid Build Coastguard Worker     Run();
199*635a8641SAndroid Build Coastguard Worker   }
200*635a8641SAndroid Build Coastguard Worker 
OnListenerThreadShutdown1(WaitableEvent * listener_event,WaitableEvent * ipc_event)201*635a8641SAndroid Build Coastguard Worker   void OnListenerThreadShutdown1(WaitableEvent* listener_event,
202*635a8641SAndroid Build Coastguard Worker                                  WaitableEvent* ipc_event) {
203*635a8641SAndroid Build Coastguard Worker     // SyncChannel needs to be destructed on the thread that it was created on.
204*635a8641SAndroid Build Coastguard Worker     channel_.reset();
205*635a8641SAndroid Build Coastguard Worker 
206*635a8641SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
207*635a8641SAndroid Build Coastguard Worker 
208*635a8641SAndroid Build Coastguard Worker     ipc_thread_.task_runner()->PostTask(
209*635a8641SAndroid Build Coastguard Worker         FROM_HERE,
210*635a8641SAndroid Build Coastguard Worker         base::Bind(&Worker::OnIPCThreadShutdown, base::Unretained(this),
211*635a8641SAndroid Build Coastguard Worker                    listener_event, ipc_event));
212*635a8641SAndroid Build Coastguard Worker   }
213*635a8641SAndroid Build Coastguard Worker 
OnIPCThreadShutdown(WaitableEvent * listener_event,WaitableEvent * ipc_event)214*635a8641SAndroid Build Coastguard Worker   void OnIPCThreadShutdown(WaitableEvent* listener_event,
215*635a8641SAndroid Build Coastguard Worker                            WaitableEvent* ipc_event) {
216*635a8641SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
217*635a8641SAndroid Build Coastguard Worker     ipc_event->Signal();
218*635a8641SAndroid Build Coastguard Worker 
219*635a8641SAndroid Build Coastguard Worker     listener_thread_.task_runner()->PostTask(
220*635a8641SAndroid Build Coastguard Worker         FROM_HERE, base::Bind(&Worker::OnListenerThreadShutdown2,
221*635a8641SAndroid Build Coastguard Worker                               base::Unretained(this), listener_event));
222*635a8641SAndroid Build Coastguard Worker   }
223*635a8641SAndroid Build Coastguard Worker 
OnListenerThreadShutdown2(WaitableEvent * listener_event)224*635a8641SAndroid Build Coastguard Worker   void OnListenerThreadShutdown2(WaitableEvent* listener_event) {
225*635a8641SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
226*635a8641SAndroid Build Coastguard Worker     listener_event->Signal();
227*635a8641SAndroid Build Coastguard Worker   }
228*635a8641SAndroid Build Coastguard Worker 
OnMessageReceived(const Message & message)229*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const Message& message) override {
230*635a8641SAndroid Build Coastguard Worker     IPC_BEGIN_MESSAGE_MAP(Worker, message)
231*635a8641SAndroid Build Coastguard Worker      IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_Double, OnDoubleDelay)
232*635a8641SAndroid Build Coastguard Worker      IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_AnswerToLife,
233*635a8641SAndroid Build Coastguard Worker                                      OnAnswerDelay)
234*635a8641SAndroid Build Coastguard Worker      IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelNestedTestMsg_String,
235*635a8641SAndroid Build Coastguard Worker                                      OnNestedTestMsg)
236*635a8641SAndroid Build Coastguard Worker     IPC_END_MESSAGE_MAP()
237*635a8641SAndroid Build Coastguard Worker     return true;
238*635a8641SAndroid Build Coastguard Worker   }
239*635a8641SAndroid Build Coastguard Worker 
StartThread(base::Thread * thread,base::MessageLoop::Type type)240*635a8641SAndroid Build Coastguard Worker   void StartThread(base::Thread* thread, base::MessageLoop::Type type) {
241*635a8641SAndroid Build Coastguard Worker     base::Thread::Options options;
242*635a8641SAndroid Build Coastguard Worker     options.message_loop_type = type;
243*635a8641SAndroid Build Coastguard Worker     thread->StartWithOptions(options);
244*635a8641SAndroid Build Coastguard Worker   }
245*635a8641SAndroid Build Coastguard Worker 
246*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<WaitableEvent> done_;
247*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<WaitableEvent> channel_created_;
248*635a8641SAndroid Build Coastguard Worker   mojo::ScopedMessagePipeHandle channel_handle_;
249*635a8641SAndroid Build Coastguard Worker   Channel::Mode mode_;
250*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<SyncChannel> channel_;
251*635a8641SAndroid Build Coastguard Worker   base::Thread ipc_thread_;
252*635a8641SAndroid Build Coastguard Worker   base::Thread listener_thread_;
253*635a8641SAndroid Build Coastguard Worker   base::Thread* overrided_thread_;
254*635a8641SAndroid Build Coastguard Worker 
255*635a8641SAndroid Build Coastguard Worker   base::WaitableEvent shutdown_event_;
256*635a8641SAndroid Build Coastguard Worker 
257*635a8641SAndroid Build Coastguard Worker   bool is_shutdown_;
258*635a8641SAndroid Build Coastguard Worker 
259*635a8641SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(Worker);
260*635a8641SAndroid Build Coastguard Worker };
261*635a8641SAndroid Build Coastguard Worker 
262*635a8641SAndroid Build Coastguard Worker 
263*635a8641SAndroid Build Coastguard Worker // Starts the test with the given workers.  This function deletes the workers
264*635a8641SAndroid Build Coastguard Worker // when it's done.
RunTest(std::vector<Worker * > workers)265*635a8641SAndroid Build Coastguard Worker void RunTest(std::vector<Worker*> workers) {
266*635a8641SAndroid Build Coastguard Worker   // First we create the workers that are channel servers, or else the other
267*635a8641SAndroid Build Coastguard Worker   // workers' channel initialization might fail because the pipe isn't created..
268*635a8641SAndroid Build Coastguard Worker   for (size_t i = 0; i < workers.size(); ++i) {
269*635a8641SAndroid Build Coastguard Worker     if (workers[i]->mode() & Channel::MODE_SERVER_FLAG) {
270*635a8641SAndroid Build Coastguard Worker       workers[i]->Start();
271*635a8641SAndroid Build Coastguard Worker       workers[i]->WaitForChannelCreation();
272*635a8641SAndroid Build Coastguard Worker     }
273*635a8641SAndroid Build Coastguard Worker   }
274*635a8641SAndroid Build Coastguard Worker 
275*635a8641SAndroid Build Coastguard Worker   // now create the clients
276*635a8641SAndroid Build Coastguard Worker   for (size_t i = 0; i < workers.size(); ++i) {
277*635a8641SAndroid Build Coastguard Worker     if (workers[i]->mode() & Channel::MODE_CLIENT_FLAG)
278*635a8641SAndroid Build Coastguard Worker       workers[i]->Start();
279*635a8641SAndroid Build Coastguard Worker   }
280*635a8641SAndroid Build Coastguard Worker 
281*635a8641SAndroid Build Coastguard Worker   // wait for all the workers to finish
282*635a8641SAndroid Build Coastguard Worker   for (size_t i = 0; i < workers.size(); ++i)
283*635a8641SAndroid Build Coastguard Worker     workers[i]->done_event()->Wait();
284*635a8641SAndroid Build Coastguard Worker 
285*635a8641SAndroid Build Coastguard Worker   for (size_t i = 0; i < workers.size(); ++i) {
286*635a8641SAndroid Build Coastguard Worker     workers[i]->Shutdown();
287*635a8641SAndroid Build Coastguard Worker     delete workers[i];
288*635a8641SAndroid Build Coastguard Worker   }
289*635a8641SAndroid Build Coastguard Worker }
290*635a8641SAndroid Build Coastguard Worker 
291*635a8641SAndroid Build Coastguard Worker class IPCSyncChannelTest : public testing::Test {
292*635a8641SAndroid Build Coastguard Worker  private:
293*635a8641SAndroid Build Coastguard Worker   base::MessageLoop message_loop_;
294*635a8641SAndroid Build Coastguard Worker };
295*635a8641SAndroid Build Coastguard Worker 
296*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
297*635a8641SAndroid Build Coastguard Worker 
298*635a8641SAndroid Build Coastguard Worker class SimpleServer : public Worker {
299*635a8641SAndroid Build Coastguard Worker  public:
SimpleServer(bool pump_during_send,mojo::ScopedMessagePipeHandle channel_handle)300*635a8641SAndroid Build Coastguard Worker   SimpleServer(bool pump_during_send,
301*635a8641SAndroid Build Coastguard Worker                mojo::ScopedMessagePipeHandle channel_handle)
302*635a8641SAndroid Build Coastguard Worker       : Worker(Channel::MODE_SERVER,
303*635a8641SAndroid Build Coastguard Worker                "simpler_server",
304*635a8641SAndroid Build Coastguard Worker                std::move(channel_handle)),
305*635a8641SAndroid Build Coastguard Worker         pump_during_send_(pump_during_send) {}
Run()306*635a8641SAndroid Build Coastguard Worker   void Run() override {
307*635a8641SAndroid Build Coastguard Worker     SendAnswerToLife(pump_during_send_, true);
308*635a8641SAndroid Build Coastguard Worker     Done();
309*635a8641SAndroid Build Coastguard Worker   }
310*635a8641SAndroid Build Coastguard Worker 
311*635a8641SAndroid Build Coastguard Worker   bool pump_during_send_;
312*635a8641SAndroid Build Coastguard Worker };
313*635a8641SAndroid Build Coastguard Worker 
314*635a8641SAndroid Build Coastguard Worker class SimpleClient : public Worker {
315*635a8641SAndroid Build Coastguard Worker  public:
SimpleClient(mojo::ScopedMessagePipeHandle channel_handle)316*635a8641SAndroid Build Coastguard Worker   explicit SimpleClient(mojo::ScopedMessagePipeHandle channel_handle)
317*635a8641SAndroid Build Coastguard Worker       : Worker(Channel::MODE_CLIENT,
318*635a8641SAndroid Build Coastguard Worker                "simple_client",
319*635a8641SAndroid Build Coastguard Worker                std::move(channel_handle)) {}
320*635a8641SAndroid Build Coastguard Worker 
OnAnswer(int * answer)321*635a8641SAndroid Build Coastguard Worker   void OnAnswer(int* answer) override {
322*635a8641SAndroid Build Coastguard Worker     *answer = 42;
323*635a8641SAndroid Build Coastguard Worker     Done();
324*635a8641SAndroid Build Coastguard Worker   }
325*635a8641SAndroid Build Coastguard Worker };
326*635a8641SAndroid Build Coastguard Worker 
Simple(bool pump_during_send)327*635a8641SAndroid Build Coastguard Worker void Simple(bool pump_during_send) {
328*635a8641SAndroid Build Coastguard Worker   std::vector<Worker*> workers;
329*635a8641SAndroid Build Coastguard Worker   mojo::MessagePipe pipe;
330*635a8641SAndroid Build Coastguard Worker   workers.push_back(
331*635a8641SAndroid Build Coastguard Worker       new SimpleServer(pump_during_send, std::move(pipe.handle0)));
332*635a8641SAndroid Build Coastguard Worker   workers.push_back(new SimpleClient(std::move(pipe.handle1)));
333*635a8641SAndroid Build Coastguard Worker   RunTest(workers);
334*635a8641SAndroid Build Coastguard Worker }
335*635a8641SAndroid Build Coastguard Worker 
336*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
337*635a8641SAndroid Build Coastguard Worker #define MAYBE_Simple DISABLED_Simple
338*635a8641SAndroid Build Coastguard Worker #else
339*635a8641SAndroid Build Coastguard Worker #define MAYBE_Simple Simple
340*635a8641SAndroid Build Coastguard Worker #endif
341*635a8641SAndroid Build Coastguard Worker // Tests basic synchronous call
TEST_F(IPCSyncChannelTest,MAYBE_Simple)342*635a8641SAndroid Build Coastguard Worker TEST_F(IPCSyncChannelTest, MAYBE_Simple) {
343*635a8641SAndroid Build Coastguard Worker   Simple(false);
344*635a8641SAndroid Build Coastguard Worker   Simple(true);
345*635a8641SAndroid Build Coastguard Worker }
346*635a8641SAndroid Build Coastguard Worker 
347*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
348*635a8641SAndroid Build Coastguard Worker 
349*635a8641SAndroid Build Coastguard Worker // Worker classes which override how the sync channel is created to use the
350*635a8641SAndroid Build Coastguard Worker // two-step initialization (calling the lightweight constructor and then
351*635a8641SAndroid Build Coastguard Worker // ChannelProxy::Init separately) process.
352*635a8641SAndroid Build Coastguard Worker class TwoStepServer : public Worker {
353*635a8641SAndroid Build Coastguard Worker  public:
TwoStepServer(bool create_pipe_now,mojo::ScopedMessagePipeHandle channel_handle)354*635a8641SAndroid Build Coastguard Worker   TwoStepServer(bool create_pipe_now,
355*635a8641SAndroid Build Coastguard Worker                 mojo::ScopedMessagePipeHandle channel_handle)
356*635a8641SAndroid Build Coastguard Worker       : Worker(Channel::MODE_SERVER,
357*635a8641SAndroid Build Coastguard Worker                "simpler_server",
358*635a8641SAndroid Build Coastguard Worker                std::move(channel_handle)),
359*635a8641SAndroid Build Coastguard Worker         create_pipe_now_(create_pipe_now) {}
360*635a8641SAndroid Build Coastguard Worker 
Run()361*635a8641SAndroid Build Coastguard Worker   void Run() override {
362*635a8641SAndroid Build Coastguard Worker     SendAnswerToLife(false, true);
363*635a8641SAndroid Build Coastguard Worker     Done();
364*635a8641SAndroid Build Coastguard Worker   }
365*635a8641SAndroid Build Coastguard Worker 
CreateChannel()366*635a8641SAndroid Build Coastguard Worker   SyncChannel* CreateChannel() override {
367*635a8641SAndroid Build Coastguard Worker     SyncChannel* channel =
368*635a8641SAndroid Build Coastguard Worker         SyncChannel::Create(TakeChannelHandle(), mode(), this,
369*635a8641SAndroid Build Coastguard Worker                             ipc_thread().task_runner(),
370*635a8641SAndroid Build Coastguard Worker                             base::ThreadTaskRunnerHandle::Get(),
371*635a8641SAndroid Build Coastguard Worker                             create_pipe_now_, shutdown_event())
372*635a8641SAndroid Build Coastguard Worker             .release();
373*635a8641SAndroid Build Coastguard Worker     return channel;
374*635a8641SAndroid Build Coastguard Worker   }
375*635a8641SAndroid Build Coastguard Worker 
376*635a8641SAndroid Build Coastguard Worker   bool create_pipe_now_;
377*635a8641SAndroid Build Coastguard Worker };
378*635a8641SAndroid Build Coastguard Worker 
379*635a8641SAndroid Build Coastguard Worker class TwoStepClient : public Worker {
380*635a8641SAndroid Build Coastguard Worker  public:
TwoStepClient(bool create_pipe_now,mojo::ScopedMessagePipeHandle channel_handle)381*635a8641SAndroid Build Coastguard Worker   TwoStepClient(bool create_pipe_now,
382*635a8641SAndroid Build Coastguard Worker                 mojo::ScopedMessagePipeHandle channel_handle)
383*635a8641SAndroid Build Coastguard Worker       : Worker(Channel::MODE_CLIENT,
384*635a8641SAndroid Build Coastguard Worker                "simple_client",
385*635a8641SAndroid Build Coastguard Worker                std::move(channel_handle)),
386*635a8641SAndroid Build Coastguard Worker         create_pipe_now_(create_pipe_now) {}
387*635a8641SAndroid Build Coastguard Worker 
OnAnswer(int * answer)388*635a8641SAndroid Build Coastguard Worker   void OnAnswer(int* answer) override {
389*635a8641SAndroid Build Coastguard Worker     *answer = 42;
390*635a8641SAndroid Build Coastguard Worker     Done();
391*635a8641SAndroid Build Coastguard Worker   }
392*635a8641SAndroid Build Coastguard Worker 
CreateChannel()393*635a8641SAndroid Build Coastguard Worker   SyncChannel* CreateChannel() override {
394*635a8641SAndroid Build Coastguard Worker     SyncChannel* channel =
395*635a8641SAndroid Build Coastguard Worker         SyncChannel::Create(TakeChannelHandle(), mode(), this,
396*635a8641SAndroid Build Coastguard Worker                             ipc_thread().task_runner(),
397*635a8641SAndroid Build Coastguard Worker                             base::ThreadTaskRunnerHandle::Get(),
398*635a8641SAndroid Build Coastguard Worker                             create_pipe_now_, shutdown_event())
399*635a8641SAndroid Build Coastguard Worker             .release();
400*635a8641SAndroid Build Coastguard Worker     return channel;
401*635a8641SAndroid Build Coastguard Worker   }
402*635a8641SAndroid Build Coastguard Worker 
403*635a8641SAndroid Build Coastguard Worker   bool create_pipe_now_;
404*635a8641SAndroid Build Coastguard Worker };
405*635a8641SAndroid Build Coastguard Worker 
TwoStep(bool create_server_pipe_now,bool create_client_pipe_now)406*635a8641SAndroid Build Coastguard Worker void TwoStep(bool create_server_pipe_now, bool create_client_pipe_now) {
407*635a8641SAndroid Build Coastguard Worker   std::vector<Worker*> workers;
408*635a8641SAndroid Build Coastguard Worker   mojo::MessagePipe pipe;
409*635a8641SAndroid Build Coastguard Worker   workers.push_back(
410*635a8641SAndroid Build Coastguard Worker       new TwoStepServer(create_server_pipe_now, std::move(pipe.handle0)));
411*635a8641SAndroid Build Coastguard Worker   workers.push_back(
412*635a8641SAndroid Build Coastguard Worker       new TwoStepClient(create_client_pipe_now, std::move(pipe.handle1)));
413*635a8641SAndroid Build Coastguard Worker   RunTest(workers);
414*635a8641SAndroid Build Coastguard Worker }
415*635a8641SAndroid Build Coastguard Worker 
416*635a8641SAndroid Build Coastguard Worker // Tests basic two-step initialization, where you call the lightweight
417*635a8641SAndroid Build Coastguard Worker // constructor then Init.
TEST_F(IPCSyncChannelTest,TwoStepInitialization)418*635a8641SAndroid Build Coastguard Worker TEST_F(IPCSyncChannelTest, TwoStepInitialization) {
419*635a8641SAndroid Build Coastguard Worker   TwoStep(false, false);
420*635a8641SAndroid Build Coastguard Worker   TwoStep(false, true);
421*635a8641SAndroid Build Coastguard Worker   TwoStep(true, false);
422*635a8641SAndroid Build Coastguard Worker   TwoStep(true, true);
423*635a8641SAndroid Build Coastguard Worker }
424*635a8641SAndroid Build Coastguard Worker 
425*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
426*635a8641SAndroid Build Coastguard Worker 
427*635a8641SAndroid Build Coastguard Worker class DelayClient : public Worker {
428*635a8641SAndroid Build Coastguard Worker  public:
DelayClient(mojo::ScopedMessagePipeHandle channel_handle)429*635a8641SAndroid Build Coastguard Worker   explicit DelayClient(mojo::ScopedMessagePipeHandle channel_handle)
430*635a8641SAndroid Build Coastguard Worker       : Worker(Channel::MODE_CLIENT,
431*635a8641SAndroid Build Coastguard Worker                "delay_client",
432*635a8641SAndroid Build Coastguard Worker                std::move(channel_handle)) {}
433*635a8641SAndroid Build Coastguard Worker 
OnAnswerDelay(Message * reply_msg)434*635a8641SAndroid Build Coastguard Worker   void OnAnswerDelay(Message* reply_msg) override {
435*635a8641SAndroid Build Coastguard Worker     SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42);
436*635a8641SAndroid Build Coastguard Worker     Send(reply_msg);
437*635a8641SAndroid Build Coastguard Worker     Done();
438*635a8641SAndroid Build Coastguard Worker   }
439*635a8641SAndroid Build Coastguard Worker };
440*635a8641SAndroid Build Coastguard Worker 
DelayReply(bool pump_during_send)441*635a8641SAndroid Build Coastguard Worker void DelayReply(bool pump_during_send) {
442*635a8641SAndroid Build Coastguard Worker   std::vector<Worker*> workers;
443*635a8641SAndroid Build Coastguard Worker   mojo::MessagePipe pipe;
444*635a8641SAndroid Build Coastguard Worker   workers.push_back(
445*635a8641SAndroid Build Coastguard Worker       new SimpleServer(pump_during_send, std::move(pipe.handle0)));
446*635a8641SAndroid Build Coastguard Worker   workers.push_back(new DelayClient(std::move(pipe.handle1)));
447*635a8641SAndroid Build Coastguard Worker   RunTest(workers);
448*635a8641SAndroid Build Coastguard Worker }
449*635a8641SAndroid Build Coastguard Worker 
450*635a8641SAndroid Build Coastguard Worker // Tests that asynchronous replies work
TEST_F(IPCSyncChannelTest,DelayReply)451*635a8641SAndroid Build Coastguard Worker TEST_F(IPCSyncChannelTest, DelayReply) {
452*635a8641SAndroid Build Coastguard Worker   DelayReply(false);
453*635a8641SAndroid Build Coastguard Worker   DelayReply(true);
454*635a8641SAndroid Build Coastguard Worker }
455*635a8641SAndroid Build Coastguard Worker 
456*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
457*635a8641SAndroid Build Coastguard Worker 
458*635a8641SAndroid Build Coastguard Worker class NoHangServer : public Worker {
459*635a8641SAndroid Build Coastguard Worker  public:
NoHangServer(WaitableEvent * got_first_reply,bool pump_during_send,mojo::ScopedMessagePipeHandle channel_handle)460*635a8641SAndroid Build Coastguard Worker   NoHangServer(WaitableEvent* got_first_reply,
461*635a8641SAndroid Build Coastguard Worker                bool pump_during_send,
462*635a8641SAndroid Build Coastguard Worker                mojo::ScopedMessagePipeHandle channel_handle)
463*635a8641SAndroid Build Coastguard Worker       : Worker(Channel::MODE_SERVER,
464*635a8641SAndroid Build Coastguard Worker                "no_hang_server",
465*635a8641SAndroid Build Coastguard Worker                std::move(channel_handle)),
466*635a8641SAndroid Build Coastguard Worker         got_first_reply_(got_first_reply),
467*635a8641SAndroid Build Coastguard Worker         pump_during_send_(pump_during_send) {}
Run()468*635a8641SAndroid Build Coastguard Worker   void Run() override {
469*635a8641SAndroid Build Coastguard Worker     SendAnswerToLife(pump_during_send_, true);
470*635a8641SAndroid Build Coastguard Worker     got_first_reply_->Signal();
471*635a8641SAndroid Build Coastguard Worker 
472*635a8641SAndroid Build Coastguard Worker     SendAnswerToLife(pump_during_send_, false);
473*635a8641SAndroid Build Coastguard Worker     Done();
474*635a8641SAndroid Build Coastguard Worker   }
475*635a8641SAndroid Build Coastguard Worker 
476*635a8641SAndroid Build Coastguard Worker   WaitableEvent* got_first_reply_;
477*635a8641SAndroid Build Coastguard Worker   bool pump_during_send_;
478*635a8641SAndroid Build Coastguard Worker };
479*635a8641SAndroid Build Coastguard Worker 
480*635a8641SAndroid Build Coastguard Worker class NoHangClient : public Worker {
481*635a8641SAndroid Build Coastguard Worker  public:
NoHangClient(WaitableEvent * got_first_reply,mojo::ScopedMessagePipeHandle channel_handle)482*635a8641SAndroid Build Coastguard Worker   NoHangClient(WaitableEvent* got_first_reply,
483*635a8641SAndroid Build Coastguard Worker                mojo::ScopedMessagePipeHandle channel_handle)
484*635a8641SAndroid Build Coastguard Worker       : Worker(Channel::MODE_CLIENT,
485*635a8641SAndroid Build Coastguard Worker                "no_hang_client",
486*635a8641SAndroid Build Coastguard Worker                std::move(channel_handle)),
487*635a8641SAndroid Build Coastguard Worker         got_first_reply_(got_first_reply) {}
488*635a8641SAndroid Build Coastguard Worker 
OnAnswerDelay(Message * reply_msg)489*635a8641SAndroid Build Coastguard Worker   void OnAnswerDelay(Message* reply_msg) override {
490*635a8641SAndroid Build Coastguard Worker     // Use the DELAY_REPLY macro so that we can force the reply to be sent
491*635a8641SAndroid Build Coastguard Worker     // before this function returns (when the channel will be reset).
492*635a8641SAndroid Build Coastguard Worker     SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42);
493*635a8641SAndroid Build Coastguard Worker     Send(reply_msg);
494*635a8641SAndroid Build Coastguard Worker     got_first_reply_->Wait();
495*635a8641SAndroid Build Coastguard Worker     CloseChannel();
496*635a8641SAndroid Build Coastguard Worker     Done();
497*635a8641SAndroid Build Coastguard Worker   }
498*635a8641SAndroid Build Coastguard Worker 
499*635a8641SAndroid Build Coastguard Worker   WaitableEvent* got_first_reply_;
500*635a8641SAndroid Build Coastguard Worker };
501*635a8641SAndroid Build Coastguard Worker 
NoHang(bool pump_during_send)502*635a8641SAndroid Build Coastguard Worker void NoHang(bool pump_during_send) {
503*635a8641SAndroid Build Coastguard Worker   WaitableEvent got_first_reply(
504*635a8641SAndroid Build Coastguard Worker       base::WaitableEvent::ResetPolicy::AUTOMATIC,
505*635a8641SAndroid Build Coastguard Worker       base::WaitableEvent::InitialState::NOT_SIGNALED);
506*635a8641SAndroid Build Coastguard Worker   std::vector<Worker*> workers;
507*635a8641SAndroid Build Coastguard Worker   mojo::MessagePipe pipe;
508*635a8641SAndroid Build Coastguard Worker   workers.push_back(new NoHangServer(&got_first_reply, pump_during_send,
509*635a8641SAndroid Build Coastguard Worker                                      std::move(pipe.handle0)));
510*635a8641SAndroid Build Coastguard Worker   workers.push_back(
511*635a8641SAndroid Build Coastguard Worker       new NoHangClient(&got_first_reply, std::move(pipe.handle1)));
512*635a8641SAndroid Build Coastguard Worker   RunTest(workers);
513*635a8641SAndroid Build Coastguard Worker }
514*635a8641SAndroid Build Coastguard Worker 
515*635a8641SAndroid Build Coastguard Worker // Tests that caller doesn't hang if receiver dies
TEST_F(IPCSyncChannelTest,NoHang)516*635a8641SAndroid Build Coastguard Worker TEST_F(IPCSyncChannelTest, NoHang) {
517*635a8641SAndroid Build Coastguard Worker   NoHang(false);
518*635a8641SAndroid Build Coastguard Worker   NoHang(true);
519*635a8641SAndroid Build Coastguard Worker }
520*635a8641SAndroid Build Coastguard Worker 
521*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
522*635a8641SAndroid Build Coastguard Worker 
523*635a8641SAndroid Build Coastguard Worker class UnblockServer : public Worker {
524*635a8641SAndroid Build Coastguard Worker  public:
UnblockServer(bool pump_during_send,bool delete_during_send,mojo::ScopedMessagePipeHandle channel_handle)525*635a8641SAndroid Build Coastguard Worker   UnblockServer(bool pump_during_send,
526*635a8641SAndroid Build Coastguard Worker                 bool delete_during_send,
527*635a8641SAndroid Build Coastguard Worker                 mojo::ScopedMessagePipeHandle channel_handle)
528*635a8641SAndroid Build Coastguard Worker       : Worker(Channel::MODE_SERVER,
529*635a8641SAndroid Build Coastguard Worker                "unblock_server",
530*635a8641SAndroid Build Coastguard Worker                std::move(channel_handle)),
531*635a8641SAndroid Build Coastguard Worker         pump_during_send_(pump_during_send),
532*635a8641SAndroid Build Coastguard Worker         delete_during_send_(delete_during_send) {}
Run()533*635a8641SAndroid Build Coastguard Worker   void Run() override {
534*635a8641SAndroid Build Coastguard Worker     if (delete_during_send_) {
535*635a8641SAndroid Build Coastguard Worker       // Use custom code since race conditions mean the answer may or may not be
536*635a8641SAndroid Build Coastguard Worker       // available.
537*635a8641SAndroid Build Coastguard Worker       int answer = 0;
538*635a8641SAndroid Build Coastguard Worker       SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer);
539*635a8641SAndroid Build Coastguard Worker       if (pump_during_send_)
540*635a8641SAndroid Build Coastguard Worker         msg->EnableMessagePumping();
541*635a8641SAndroid Build Coastguard Worker       Send(msg);
542*635a8641SAndroid Build Coastguard Worker     } else {
543*635a8641SAndroid Build Coastguard Worker       SendAnswerToLife(pump_during_send_, true);
544*635a8641SAndroid Build Coastguard Worker     }
545*635a8641SAndroid Build Coastguard Worker     Done();
546*635a8641SAndroid Build Coastguard Worker   }
547*635a8641SAndroid Build Coastguard Worker 
OnDoubleDelay(int in,Message * reply_msg)548*635a8641SAndroid Build Coastguard Worker   void OnDoubleDelay(int in, Message* reply_msg) override {
549*635a8641SAndroid Build Coastguard Worker     SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, in * 2);
550*635a8641SAndroid Build Coastguard Worker     Send(reply_msg);
551*635a8641SAndroid Build Coastguard Worker     if (delete_during_send_)
552*635a8641SAndroid Build Coastguard Worker       ResetChannel();
553*635a8641SAndroid Build Coastguard Worker   }
554*635a8641SAndroid Build Coastguard Worker 
555*635a8641SAndroid Build Coastguard Worker   bool pump_during_send_;
556*635a8641SAndroid Build Coastguard Worker   bool delete_during_send_;
557*635a8641SAndroid Build Coastguard Worker };
558*635a8641SAndroid Build Coastguard Worker 
559*635a8641SAndroid Build Coastguard Worker class UnblockClient : public Worker {
560*635a8641SAndroid Build Coastguard Worker  public:
UnblockClient(bool pump_during_send,mojo::ScopedMessagePipeHandle channel_handle)561*635a8641SAndroid Build Coastguard Worker   UnblockClient(bool pump_during_send,
562*635a8641SAndroid Build Coastguard Worker                 mojo::ScopedMessagePipeHandle channel_handle)
563*635a8641SAndroid Build Coastguard Worker       : Worker(Channel::MODE_CLIENT,
564*635a8641SAndroid Build Coastguard Worker                "unblock_client",
565*635a8641SAndroid Build Coastguard Worker                std::move(channel_handle)),
566*635a8641SAndroid Build Coastguard Worker         pump_during_send_(pump_during_send) {}
567*635a8641SAndroid Build Coastguard Worker 
OnAnswer(int * answer)568*635a8641SAndroid Build Coastguard Worker   void OnAnswer(int* answer) override {
569*635a8641SAndroid Build Coastguard Worker     SendDouble(pump_during_send_, true);
570*635a8641SAndroid Build Coastguard Worker     *answer = 42;
571*635a8641SAndroid Build Coastguard Worker     Done();
572*635a8641SAndroid Build Coastguard Worker   }
573*635a8641SAndroid Build Coastguard Worker 
574*635a8641SAndroid Build Coastguard Worker   bool pump_during_send_;
575*635a8641SAndroid Build Coastguard Worker };
576*635a8641SAndroid Build Coastguard Worker 
Unblock(bool server_pump,bool client_pump,bool delete_during_send)577*635a8641SAndroid Build Coastguard Worker void Unblock(bool server_pump, bool client_pump, bool delete_during_send) {
578*635a8641SAndroid Build Coastguard Worker   std::vector<Worker*> workers;
579*635a8641SAndroid Build Coastguard Worker   mojo::MessagePipe pipe;
580*635a8641SAndroid Build Coastguard Worker   workers.push_back(new UnblockServer(server_pump, delete_during_send,
581*635a8641SAndroid Build Coastguard Worker                                       std::move(pipe.handle0)));
582*635a8641SAndroid Build Coastguard Worker   workers.push_back(new UnblockClient(client_pump, std::move(pipe.handle1)));
583*635a8641SAndroid Build Coastguard Worker   RunTest(workers);
584*635a8641SAndroid Build Coastguard Worker }
585*635a8641SAndroid Build Coastguard Worker 
586*635a8641SAndroid Build Coastguard Worker // Tests that the caller unblocks to answer a sync message from the receiver.
TEST_F(IPCSyncChannelTest,Unblock)587*635a8641SAndroid Build Coastguard Worker TEST_F(IPCSyncChannelTest, Unblock) {
588*635a8641SAndroid Build Coastguard Worker   Unblock(false, false, false);
589*635a8641SAndroid Build Coastguard Worker   Unblock(false, true, false);
590*635a8641SAndroid Build Coastguard Worker   Unblock(true, false, false);
591*635a8641SAndroid Build Coastguard Worker   Unblock(true, true, false);
592*635a8641SAndroid Build Coastguard Worker }
593*635a8641SAndroid Build Coastguard Worker 
594*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
595*635a8641SAndroid Build Coastguard Worker 
596*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
597*635a8641SAndroid Build Coastguard Worker #define MAYBE_ChannelDeleteDuringSend DISABLED_ChannelDeleteDuringSend
598*635a8641SAndroid Build Coastguard Worker #else
599*635a8641SAndroid Build Coastguard Worker #define MAYBE_ChannelDeleteDuringSend ChannelDeleteDuringSend
600*635a8641SAndroid Build Coastguard Worker #endif
601*635a8641SAndroid Build Coastguard Worker // Tests that the the SyncChannel object can be deleted during a Send.
TEST_F(IPCSyncChannelTest,MAYBE_ChannelDeleteDuringSend)602*635a8641SAndroid Build Coastguard Worker TEST_F(IPCSyncChannelTest, MAYBE_ChannelDeleteDuringSend) {
603*635a8641SAndroid Build Coastguard Worker   Unblock(false, false, true);
604*635a8641SAndroid Build Coastguard Worker   Unblock(false, true, true);
605*635a8641SAndroid Build Coastguard Worker   Unblock(true, false, true);
606*635a8641SAndroid Build Coastguard Worker   Unblock(true, true, true);
607*635a8641SAndroid Build Coastguard Worker }
608*635a8641SAndroid Build Coastguard Worker 
609*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
610*635a8641SAndroid Build Coastguard Worker 
611*635a8641SAndroid Build Coastguard Worker class RecursiveServer : public Worker {
612*635a8641SAndroid Build Coastguard Worker  public:
RecursiveServer(bool expected_send_result,bool pump_first,bool pump_second,mojo::ScopedMessagePipeHandle channel_handle)613*635a8641SAndroid Build Coastguard Worker   RecursiveServer(bool expected_send_result,
614*635a8641SAndroid Build Coastguard Worker                   bool pump_first,
615*635a8641SAndroid Build Coastguard Worker                   bool pump_second,
616*635a8641SAndroid Build Coastguard Worker                   mojo::ScopedMessagePipeHandle channel_handle)
617*635a8641SAndroid Build Coastguard Worker       : Worker(Channel::MODE_SERVER,
618*635a8641SAndroid Build Coastguard Worker                "recursive_server",
619*635a8641SAndroid Build Coastguard Worker                std::move(channel_handle)),
620*635a8641SAndroid Build Coastguard Worker         expected_send_result_(expected_send_result),
621*635a8641SAndroid Build Coastguard Worker         pump_first_(pump_first),
622*635a8641SAndroid Build Coastguard Worker         pump_second_(pump_second) {}
Run()623*635a8641SAndroid Build Coastguard Worker   void Run() override {
624*635a8641SAndroid Build Coastguard Worker     SendDouble(pump_first_, expected_send_result_);
625*635a8641SAndroid Build Coastguard Worker     Done();
626*635a8641SAndroid Build Coastguard Worker   }
627*635a8641SAndroid Build Coastguard Worker 
OnDouble(int in,int * out)628*635a8641SAndroid Build Coastguard Worker   void OnDouble(int in, int* out) override {
629*635a8641SAndroid Build Coastguard Worker     *out = in * 2;
630*635a8641SAndroid Build Coastguard Worker     SendAnswerToLife(pump_second_, expected_send_result_);
631*635a8641SAndroid Build Coastguard Worker   }
632*635a8641SAndroid Build Coastguard Worker 
633*635a8641SAndroid Build Coastguard Worker   bool expected_send_result_, pump_first_, pump_second_;
634*635a8641SAndroid Build Coastguard Worker };
635*635a8641SAndroid Build Coastguard Worker 
636*635a8641SAndroid Build Coastguard Worker class RecursiveClient : public Worker {
637*635a8641SAndroid Build Coastguard Worker  public:
RecursiveClient(bool pump_during_send,bool close_channel,mojo::ScopedMessagePipeHandle channel_handle)638*635a8641SAndroid Build Coastguard Worker   RecursiveClient(bool pump_during_send,
639*635a8641SAndroid Build Coastguard Worker                   bool close_channel,
640*635a8641SAndroid Build Coastguard Worker                   mojo::ScopedMessagePipeHandle channel_handle)
641*635a8641SAndroid Build Coastguard Worker       : Worker(Channel::MODE_CLIENT,
642*635a8641SAndroid Build Coastguard Worker                "recursive_client",
643*635a8641SAndroid Build Coastguard Worker                std::move(channel_handle)),
644*635a8641SAndroid Build Coastguard Worker         pump_during_send_(pump_during_send),
645*635a8641SAndroid Build Coastguard Worker         close_channel_(close_channel) {}
646*635a8641SAndroid Build Coastguard Worker 
OnDoubleDelay(int in,Message * reply_msg)647*635a8641SAndroid Build Coastguard Worker   void OnDoubleDelay(int in, Message* reply_msg) override {
648*635a8641SAndroid Build Coastguard Worker     SendDouble(pump_during_send_, !close_channel_);
649*635a8641SAndroid Build Coastguard Worker     if (close_channel_) {
650*635a8641SAndroid Build Coastguard Worker       delete reply_msg;
651*635a8641SAndroid Build Coastguard Worker     } else {
652*635a8641SAndroid Build Coastguard Worker       SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, in * 2);
653*635a8641SAndroid Build Coastguard Worker       Send(reply_msg);
654*635a8641SAndroid Build Coastguard Worker     }
655*635a8641SAndroid Build Coastguard Worker     Done();
656*635a8641SAndroid Build Coastguard Worker   }
657*635a8641SAndroid Build Coastguard Worker 
OnAnswerDelay(Message * reply_msg)658*635a8641SAndroid Build Coastguard Worker   void OnAnswerDelay(Message* reply_msg) override {
659*635a8641SAndroid Build Coastguard Worker     if (close_channel_) {
660*635a8641SAndroid Build Coastguard Worker       delete reply_msg;
661*635a8641SAndroid Build Coastguard Worker       CloseChannel();
662*635a8641SAndroid Build Coastguard Worker     } else {
663*635a8641SAndroid Build Coastguard Worker       SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42);
664*635a8641SAndroid Build Coastguard Worker       Send(reply_msg);
665*635a8641SAndroid Build Coastguard Worker     }
666*635a8641SAndroid Build Coastguard Worker   }
667*635a8641SAndroid Build Coastguard Worker 
668*635a8641SAndroid Build Coastguard Worker   bool pump_during_send_, close_channel_;
669*635a8641SAndroid Build Coastguard Worker };
670*635a8641SAndroid Build Coastguard Worker 
Recursive(bool server_pump_first,bool server_pump_second,bool client_pump)671*635a8641SAndroid Build Coastguard Worker void Recursive(
672*635a8641SAndroid Build Coastguard Worker     bool server_pump_first, bool server_pump_second, bool client_pump) {
673*635a8641SAndroid Build Coastguard Worker   std::vector<Worker*> workers;
674*635a8641SAndroid Build Coastguard Worker   mojo::MessagePipe pipe;
675*635a8641SAndroid Build Coastguard Worker   workers.push_back(new RecursiveServer(
676*635a8641SAndroid Build Coastguard Worker       true, server_pump_first, server_pump_second, std::move(pipe.handle0)));
677*635a8641SAndroid Build Coastguard Worker   workers.push_back(
678*635a8641SAndroid Build Coastguard Worker       new RecursiveClient(client_pump, false, std::move(pipe.handle1)));
679*635a8641SAndroid Build Coastguard Worker   RunTest(workers);
680*635a8641SAndroid Build Coastguard Worker }
681*635a8641SAndroid Build Coastguard Worker 
682*635a8641SAndroid Build Coastguard Worker // Tests a server calling Send while another Send is pending.
TEST_F(IPCSyncChannelTest,Recursive)683*635a8641SAndroid Build Coastguard Worker TEST_F(IPCSyncChannelTest, Recursive) {
684*635a8641SAndroid Build Coastguard Worker   Recursive(false, false, false);
685*635a8641SAndroid Build Coastguard Worker   Recursive(false, false, true);
686*635a8641SAndroid Build Coastguard Worker   Recursive(false, true, false);
687*635a8641SAndroid Build Coastguard Worker   Recursive(false, true, true);
688*635a8641SAndroid Build Coastguard Worker   Recursive(true, false, false);
689*635a8641SAndroid Build Coastguard Worker   Recursive(true, false, true);
690*635a8641SAndroid Build Coastguard Worker   Recursive(true, true, false);
691*635a8641SAndroid Build Coastguard Worker   Recursive(true, true, true);
692*635a8641SAndroid Build Coastguard Worker }
693*635a8641SAndroid Build Coastguard Worker 
694*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
695*635a8641SAndroid Build Coastguard Worker 
RecursiveNoHang(bool server_pump_first,bool server_pump_second,bool client_pump)696*635a8641SAndroid Build Coastguard Worker void RecursiveNoHang(
697*635a8641SAndroid Build Coastguard Worker     bool server_pump_first, bool server_pump_second, bool client_pump) {
698*635a8641SAndroid Build Coastguard Worker   std::vector<Worker*> workers;
699*635a8641SAndroid Build Coastguard Worker   mojo::MessagePipe pipe;
700*635a8641SAndroid Build Coastguard Worker   workers.push_back(new RecursiveServer(
701*635a8641SAndroid Build Coastguard Worker       false, server_pump_first, server_pump_second, std::move(pipe.handle0)));
702*635a8641SAndroid Build Coastguard Worker   workers.push_back(
703*635a8641SAndroid Build Coastguard Worker       new RecursiveClient(client_pump, true, std::move(pipe.handle1)));
704*635a8641SAndroid Build Coastguard Worker   RunTest(workers);
705*635a8641SAndroid Build Coastguard Worker }
706*635a8641SAndroid Build Coastguard Worker 
707*635a8641SAndroid Build Coastguard Worker // Tests that if a caller makes a sync call during an existing sync call and
708*635a8641SAndroid Build Coastguard Worker // the receiver dies, neither of the Send() calls hang.
TEST_F(IPCSyncChannelTest,RecursiveNoHang)709*635a8641SAndroid Build Coastguard Worker TEST_F(IPCSyncChannelTest, RecursiveNoHang) {
710*635a8641SAndroid Build Coastguard Worker   RecursiveNoHang(false, false, false);
711*635a8641SAndroid Build Coastguard Worker   RecursiveNoHang(false, false, true);
712*635a8641SAndroid Build Coastguard Worker   RecursiveNoHang(false, true, false);
713*635a8641SAndroid Build Coastguard Worker   RecursiveNoHang(false, true, true);
714*635a8641SAndroid Build Coastguard Worker   RecursiveNoHang(true, false, false);
715*635a8641SAndroid Build Coastguard Worker   RecursiveNoHang(true, false, true);
716*635a8641SAndroid Build Coastguard Worker   RecursiveNoHang(true, true, false);
717*635a8641SAndroid Build Coastguard Worker   RecursiveNoHang(true, true, true);
718*635a8641SAndroid Build Coastguard Worker }
719*635a8641SAndroid Build Coastguard Worker 
720*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
721*635a8641SAndroid Build Coastguard Worker 
722*635a8641SAndroid Build Coastguard Worker class MultipleServer1 : public Worker {
723*635a8641SAndroid Build Coastguard Worker  public:
MultipleServer1(bool pump_during_send,mojo::ScopedMessagePipeHandle channel_handle)724*635a8641SAndroid Build Coastguard Worker   MultipleServer1(bool pump_during_send,
725*635a8641SAndroid Build Coastguard Worker                   mojo::ScopedMessagePipeHandle channel_handle)
726*635a8641SAndroid Build Coastguard Worker       : Worker(std::move(channel_handle), Channel::MODE_SERVER),
727*635a8641SAndroid Build Coastguard Worker         pump_during_send_(pump_during_send) {}
728*635a8641SAndroid Build Coastguard Worker 
Run()729*635a8641SAndroid Build Coastguard Worker   void Run() override {
730*635a8641SAndroid Build Coastguard Worker     SendDouble(pump_during_send_, true);
731*635a8641SAndroid Build Coastguard Worker     Done();
732*635a8641SAndroid Build Coastguard Worker   }
733*635a8641SAndroid Build Coastguard Worker 
734*635a8641SAndroid Build Coastguard Worker   bool pump_during_send_;
735*635a8641SAndroid Build Coastguard Worker };
736*635a8641SAndroid Build Coastguard Worker 
737*635a8641SAndroid Build Coastguard Worker class MultipleClient1 : public Worker {
738*635a8641SAndroid Build Coastguard Worker  public:
MultipleClient1(WaitableEvent * client1_msg_received,WaitableEvent * client1_can_reply,mojo::ScopedMessagePipeHandle channel_handle)739*635a8641SAndroid Build Coastguard Worker   MultipleClient1(WaitableEvent* client1_msg_received,
740*635a8641SAndroid Build Coastguard Worker                   WaitableEvent* client1_can_reply,
741*635a8641SAndroid Build Coastguard Worker                   mojo::ScopedMessagePipeHandle channel_handle)
742*635a8641SAndroid Build Coastguard Worker       : Worker(std::move(channel_handle), Channel::MODE_CLIENT),
743*635a8641SAndroid Build Coastguard Worker         client1_msg_received_(client1_msg_received),
744*635a8641SAndroid Build Coastguard Worker         client1_can_reply_(client1_can_reply) {}
745*635a8641SAndroid Build Coastguard Worker 
OnDouble(int in,int * out)746*635a8641SAndroid Build Coastguard Worker   void OnDouble(int in, int* out) override {
747*635a8641SAndroid Build Coastguard Worker     client1_msg_received_->Signal();
748*635a8641SAndroid Build Coastguard Worker     *out = in * 2;
749*635a8641SAndroid Build Coastguard Worker     client1_can_reply_->Wait();
750*635a8641SAndroid Build Coastguard Worker     Done();
751*635a8641SAndroid Build Coastguard Worker   }
752*635a8641SAndroid Build Coastguard Worker 
753*635a8641SAndroid Build Coastguard Worker  private:
754*635a8641SAndroid Build Coastguard Worker   WaitableEvent *client1_msg_received_, *client1_can_reply_;
755*635a8641SAndroid Build Coastguard Worker };
756*635a8641SAndroid Build Coastguard Worker 
757*635a8641SAndroid Build Coastguard Worker class MultipleServer2 : public Worker {
758*635a8641SAndroid Build Coastguard Worker  public:
MultipleServer2(mojo::ScopedMessagePipeHandle channel_handle)759*635a8641SAndroid Build Coastguard Worker   explicit MultipleServer2(mojo::ScopedMessagePipeHandle channel_handle)
760*635a8641SAndroid Build Coastguard Worker       : Worker(std::move(channel_handle), Channel::MODE_SERVER) {}
761*635a8641SAndroid Build Coastguard Worker 
OnAnswer(int * result)762*635a8641SAndroid Build Coastguard Worker   void OnAnswer(int* result) override {
763*635a8641SAndroid Build Coastguard Worker     *result = 42;
764*635a8641SAndroid Build Coastguard Worker     Done();
765*635a8641SAndroid Build Coastguard Worker   }
766*635a8641SAndroid Build Coastguard Worker };
767*635a8641SAndroid Build Coastguard Worker 
768*635a8641SAndroid Build Coastguard Worker class MultipleClient2 : public Worker {
769*635a8641SAndroid Build Coastguard Worker  public:
MultipleClient2(WaitableEvent * client1_msg_received,WaitableEvent * client1_can_reply,bool pump_during_send,mojo::ScopedMessagePipeHandle channel_handle)770*635a8641SAndroid Build Coastguard Worker   MultipleClient2(WaitableEvent* client1_msg_received,
771*635a8641SAndroid Build Coastguard Worker                   WaitableEvent* client1_can_reply,
772*635a8641SAndroid Build Coastguard Worker                   bool pump_during_send,
773*635a8641SAndroid Build Coastguard Worker                   mojo::ScopedMessagePipeHandle channel_handle)
774*635a8641SAndroid Build Coastguard Worker       : Worker(std::move(channel_handle), Channel::MODE_CLIENT),
775*635a8641SAndroid Build Coastguard Worker         client1_msg_received_(client1_msg_received),
776*635a8641SAndroid Build Coastguard Worker         client1_can_reply_(client1_can_reply),
777*635a8641SAndroid Build Coastguard Worker         pump_during_send_(pump_during_send) {}
778*635a8641SAndroid Build Coastguard Worker 
Run()779*635a8641SAndroid Build Coastguard Worker   void Run() override {
780*635a8641SAndroid Build Coastguard Worker     client1_msg_received_->Wait();
781*635a8641SAndroid Build Coastguard Worker     SendAnswerToLife(pump_during_send_, true);
782*635a8641SAndroid Build Coastguard Worker     client1_can_reply_->Signal();
783*635a8641SAndroid Build Coastguard Worker     Done();
784*635a8641SAndroid Build Coastguard Worker   }
785*635a8641SAndroid Build Coastguard Worker 
786*635a8641SAndroid Build Coastguard Worker  private:
787*635a8641SAndroid Build Coastguard Worker   WaitableEvent *client1_msg_received_, *client1_can_reply_;
788*635a8641SAndroid Build Coastguard Worker   bool pump_during_send_;
789*635a8641SAndroid Build Coastguard Worker };
790*635a8641SAndroid Build Coastguard Worker 
Multiple(bool server_pump,bool client_pump)791*635a8641SAndroid Build Coastguard Worker void Multiple(bool server_pump, bool client_pump) {
792*635a8641SAndroid Build Coastguard Worker   std::vector<Worker*> workers;
793*635a8641SAndroid Build Coastguard Worker 
794*635a8641SAndroid Build Coastguard Worker   // A shared worker thread so that server1 and server2 run on one thread.
795*635a8641SAndroid Build Coastguard Worker   base::Thread worker_thread("Multiple");
796*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(worker_thread.Start());
797*635a8641SAndroid Build Coastguard Worker 
798*635a8641SAndroid Build Coastguard Worker   // Server1 sends a sync msg to client1, which blocks the reply until
799*635a8641SAndroid Build Coastguard Worker   // server2 (which runs on the same worker thread as server1) responds
800*635a8641SAndroid Build Coastguard Worker   // to a sync msg from client2.
801*635a8641SAndroid Build Coastguard Worker   WaitableEvent client1_msg_received(
802*635a8641SAndroid Build Coastguard Worker       base::WaitableEvent::ResetPolicy::AUTOMATIC,
803*635a8641SAndroid Build Coastguard Worker       base::WaitableEvent::InitialState::NOT_SIGNALED);
804*635a8641SAndroid Build Coastguard Worker   WaitableEvent client1_can_reply(
805*635a8641SAndroid Build Coastguard Worker       base::WaitableEvent::ResetPolicy::AUTOMATIC,
806*635a8641SAndroid Build Coastguard Worker       base::WaitableEvent::InitialState::NOT_SIGNALED);
807*635a8641SAndroid Build Coastguard Worker 
808*635a8641SAndroid Build Coastguard Worker   Worker* worker;
809*635a8641SAndroid Build Coastguard Worker 
810*635a8641SAndroid Build Coastguard Worker   mojo::MessagePipe pipe1, pipe2;
811*635a8641SAndroid Build Coastguard Worker   worker = new MultipleServer2(std::move(pipe2.handle0));
812*635a8641SAndroid Build Coastguard Worker   worker->OverrideThread(&worker_thread);
813*635a8641SAndroid Build Coastguard Worker   workers.push_back(worker);
814*635a8641SAndroid Build Coastguard Worker 
815*635a8641SAndroid Build Coastguard Worker   worker = new MultipleClient2(&client1_msg_received, &client1_can_reply,
816*635a8641SAndroid Build Coastguard Worker                                client_pump, std::move(pipe2.handle1));
817*635a8641SAndroid Build Coastguard Worker   workers.push_back(worker);
818*635a8641SAndroid Build Coastguard Worker 
819*635a8641SAndroid Build Coastguard Worker   worker = new MultipleServer1(server_pump, std::move(pipe1.handle0));
820*635a8641SAndroid Build Coastguard Worker   worker->OverrideThread(&worker_thread);
821*635a8641SAndroid Build Coastguard Worker   workers.push_back(worker);
822*635a8641SAndroid Build Coastguard Worker 
823*635a8641SAndroid Build Coastguard Worker   worker = new MultipleClient1(&client1_msg_received, &client1_can_reply,
824*635a8641SAndroid Build Coastguard Worker                                std::move(pipe1.handle1));
825*635a8641SAndroid Build Coastguard Worker   workers.push_back(worker);
826*635a8641SAndroid Build Coastguard Worker 
827*635a8641SAndroid Build Coastguard Worker   RunTest(workers);
828*635a8641SAndroid Build Coastguard Worker }
829*635a8641SAndroid Build Coastguard Worker 
830*635a8641SAndroid Build Coastguard Worker // Tests that multiple SyncObjects on the same listener thread can unblock each
831*635a8641SAndroid Build Coastguard Worker // other.
TEST_F(IPCSyncChannelTest,Multiple)832*635a8641SAndroid Build Coastguard Worker TEST_F(IPCSyncChannelTest, Multiple) {
833*635a8641SAndroid Build Coastguard Worker   Multiple(false, false);
834*635a8641SAndroid Build Coastguard Worker   Multiple(false, true);
835*635a8641SAndroid Build Coastguard Worker   Multiple(true, false);
836*635a8641SAndroid Build Coastguard Worker   Multiple(true, true);
837*635a8641SAndroid Build Coastguard Worker }
838*635a8641SAndroid Build Coastguard Worker 
839*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
840*635a8641SAndroid Build Coastguard Worker 
841*635a8641SAndroid Build Coastguard Worker // This class provides server side functionality to test the case where
842*635a8641SAndroid Build Coastguard Worker // multiple sync channels are in use on the same thread on the client and
843*635a8641SAndroid Build Coastguard Worker // nested calls are issued.
844*635a8641SAndroid Build Coastguard Worker class QueuedReplyServer : public Worker {
845*635a8641SAndroid Build Coastguard Worker  public:
QueuedReplyServer(base::Thread * listener_thread,mojo::ScopedMessagePipeHandle channel_handle,const std::string & reply_text)846*635a8641SAndroid Build Coastguard Worker   QueuedReplyServer(base::Thread* listener_thread,
847*635a8641SAndroid Build Coastguard Worker                     mojo::ScopedMessagePipeHandle channel_handle,
848*635a8641SAndroid Build Coastguard Worker                     const std::string& reply_text)
849*635a8641SAndroid Build Coastguard Worker       : Worker(std::move(channel_handle), Channel::MODE_SERVER),
850*635a8641SAndroid Build Coastguard Worker         reply_text_(reply_text) {
851*635a8641SAndroid Build Coastguard Worker     Worker::OverrideThread(listener_thread);
852*635a8641SAndroid Build Coastguard Worker   }
853*635a8641SAndroid Build Coastguard Worker 
OnNestedTestMsg(Message * reply_msg)854*635a8641SAndroid Build Coastguard Worker   void OnNestedTestMsg(Message* reply_msg) override {
855*635a8641SAndroid Build Coastguard Worker     VLOG(1) << __FUNCTION__ << " Sending reply: " << reply_text_;
856*635a8641SAndroid Build Coastguard Worker     SyncChannelNestedTestMsg_String::WriteReplyParams(reply_msg, reply_text_);
857*635a8641SAndroid Build Coastguard Worker     Send(reply_msg);
858*635a8641SAndroid Build Coastguard Worker     Done();
859*635a8641SAndroid Build Coastguard Worker   }
860*635a8641SAndroid Build Coastguard Worker 
861*635a8641SAndroid Build Coastguard Worker  private:
862*635a8641SAndroid Build Coastguard Worker   std::string reply_text_;
863*635a8641SAndroid Build Coastguard Worker };
864*635a8641SAndroid Build Coastguard Worker 
865*635a8641SAndroid Build Coastguard Worker // The QueuedReplyClient class provides functionality to test the case where
866*635a8641SAndroid Build Coastguard Worker // multiple sync channels are in use on the same thread and they make nested
867*635a8641SAndroid Build Coastguard Worker // sync calls, i.e. while the first channel waits for a response it makes a
868*635a8641SAndroid Build Coastguard Worker // sync call on another channel.
869*635a8641SAndroid Build Coastguard Worker // The callstack should unwind correctly, i.e. the outermost call should
870*635a8641SAndroid Build Coastguard Worker // complete first, and so on.
871*635a8641SAndroid Build Coastguard Worker class QueuedReplyClient : public Worker {
872*635a8641SAndroid Build Coastguard Worker  public:
QueuedReplyClient(base::Thread * listener_thread,mojo::ScopedMessagePipeHandle channel_handle,const std::string & expected_text,bool pump_during_send)873*635a8641SAndroid Build Coastguard Worker   QueuedReplyClient(base::Thread* listener_thread,
874*635a8641SAndroid Build Coastguard Worker                     mojo::ScopedMessagePipeHandle channel_handle,
875*635a8641SAndroid Build Coastguard Worker                     const std::string& expected_text,
876*635a8641SAndroid Build Coastguard Worker                     bool pump_during_send)
877*635a8641SAndroid Build Coastguard Worker       : Worker(std::move(channel_handle), Channel::MODE_CLIENT),
878*635a8641SAndroid Build Coastguard Worker         pump_during_send_(pump_during_send),
879*635a8641SAndroid Build Coastguard Worker         expected_text_(expected_text) {
880*635a8641SAndroid Build Coastguard Worker     Worker::OverrideThread(listener_thread);
881*635a8641SAndroid Build Coastguard Worker   }
882*635a8641SAndroid Build Coastguard Worker 
Run()883*635a8641SAndroid Build Coastguard Worker   void Run() override {
884*635a8641SAndroid Build Coastguard Worker     std::string response;
885*635a8641SAndroid Build Coastguard Worker     SyncMessage* msg = new SyncChannelNestedTestMsg_String(&response);
886*635a8641SAndroid Build Coastguard Worker     if (pump_during_send_)
887*635a8641SAndroid Build Coastguard Worker       msg->EnableMessagePumping();
888*635a8641SAndroid Build Coastguard Worker     bool result = Send(msg);
889*635a8641SAndroid Build Coastguard Worker     DCHECK(result);
890*635a8641SAndroid Build Coastguard Worker     DCHECK_EQ(response, expected_text_);
891*635a8641SAndroid Build Coastguard Worker 
892*635a8641SAndroid Build Coastguard Worker     VLOG(1) << __FUNCTION__ << " Received reply: " << response;
893*635a8641SAndroid Build Coastguard Worker     Done();
894*635a8641SAndroid Build Coastguard Worker   }
895*635a8641SAndroid Build Coastguard Worker 
896*635a8641SAndroid Build Coastguard Worker  private:
897*635a8641SAndroid Build Coastguard Worker   bool pump_during_send_;
898*635a8641SAndroid Build Coastguard Worker   std::string expected_text_;
899*635a8641SAndroid Build Coastguard Worker };
900*635a8641SAndroid Build Coastguard Worker 
QueuedReply(bool client_pump)901*635a8641SAndroid Build Coastguard Worker void QueuedReply(bool client_pump) {
902*635a8641SAndroid Build Coastguard Worker   std::vector<Worker*> workers;
903*635a8641SAndroid Build Coastguard Worker 
904*635a8641SAndroid Build Coastguard Worker   // A shared worker thread for servers
905*635a8641SAndroid Build Coastguard Worker   base::Thread server_worker_thread("QueuedReply_ServerListener");
906*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(server_worker_thread.Start());
907*635a8641SAndroid Build Coastguard Worker 
908*635a8641SAndroid Build Coastguard Worker   base::Thread client_worker_thread("QueuedReply_ClientListener");
909*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(client_worker_thread.Start());
910*635a8641SAndroid Build Coastguard Worker 
911*635a8641SAndroid Build Coastguard Worker   Worker* worker;
912*635a8641SAndroid Build Coastguard Worker 
913*635a8641SAndroid Build Coastguard Worker   mojo::MessagePipe pipe1, pipe2;
914*635a8641SAndroid Build Coastguard Worker   worker = new QueuedReplyServer(&server_worker_thread,
915*635a8641SAndroid Build Coastguard Worker                                  std::move(pipe1.handle0), "Got first message");
916*635a8641SAndroid Build Coastguard Worker   workers.push_back(worker);
917*635a8641SAndroid Build Coastguard Worker 
918*635a8641SAndroid Build Coastguard Worker   worker = new QueuedReplyServer(
919*635a8641SAndroid Build Coastguard Worker       &server_worker_thread, std::move(pipe2.handle0), "Got second message");
920*635a8641SAndroid Build Coastguard Worker   workers.push_back(worker);
921*635a8641SAndroid Build Coastguard Worker 
922*635a8641SAndroid Build Coastguard Worker   worker =
923*635a8641SAndroid Build Coastguard Worker       new QueuedReplyClient(&client_worker_thread, std::move(pipe1.handle1),
924*635a8641SAndroid Build Coastguard Worker                             "Got first message", client_pump);
925*635a8641SAndroid Build Coastguard Worker   workers.push_back(worker);
926*635a8641SAndroid Build Coastguard Worker 
927*635a8641SAndroid Build Coastguard Worker   worker =
928*635a8641SAndroid Build Coastguard Worker       new QueuedReplyClient(&client_worker_thread, std::move(pipe2.handle1),
929*635a8641SAndroid Build Coastguard Worker                             "Got second message", client_pump);
930*635a8641SAndroid Build Coastguard Worker   workers.push_back(worker);
931*635a8641SAndroid Build Coastguard Worker 
932*635a8641SAndroid Build Coastguard Worker   RunTest(workers);
933*635a8641SAndroid Build Coastguard Worker }
934*635a8641SAndroid Build Coastguard Worker 
935*635a8641SAndroid Build Coastguard Worker // While a blocking send is in progress, the listener thread might answer other
936*635a8641SAndroid Build Coastguard Worker // synchronous messages.  This tests that if during the response to another
937*635a8641SAndroid Build Coastguard Worker // message the reply to the original messages comes, it is queued up correctly
938*635a8641SAndroid Build Coastguard Worker // and the original Send is unblocked later.
939*635a8641SAndroid Build Coastguard Worker // We also test that the send call stacks unwind correctly when the channel
940*635a8641SAndroid Build Coastguard Worker // pumps messages while waiting for a response.
TEST_F(IPCSyncChannelTest,QueuedReply)941*635a8641SAndroid Build Coastguard Worker TEST_F(IPCSyncChannelTest, QueuedReply) {
942*635a8641SAndroid Build Coastguard Worker   QueuedReply(false);
943*635a8641SAndroid Build Coastguard Worker   QueuedReply(true);
944*635a8641SAndroid Build Coastguard Worker }
945*635a8641SAndroid Build Coastguard Worker 
946*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
947*635a8641SAndroid Build Coastguard Worker 
948*635a8641SAndroid Build Coastguard Worker class ChattyClient : public Worker {
949*635a8641SAndroid Build Coastguard Worker  public:
ChattyClient(mojo::ScopedMessagePipeHandle channel_handle)950*635a8641SAndroid Build Coastguard Worker   explicit ChattyClient(mojo::ScopedMessagePipeHandle channel_handle)
951*635a8641SAndroid Build Coastguard Worker       : Worker(Channel::MODE_CLIENT,
952*635a8641SAndroid Build Coastguard Worker                "chatty_client",
953*635a8641SAndroid Build Coastguard Worker                std::move(channel_handle)) {}
954*635a8641SAndroid Build Coastguard Worker 
OnAnswer(int * answer)955*635a8641SAndroid Build Coastguard Worker   void OnAnswer(int* answer) override {
956*635a8641SAndroid Build Coastguard Worker     // The PostMessage limit is 10k.  Send 20% more than that.
957*635a8641SAndroid Build Coastguard Worker     const int kMessageLimit = 10000;
958*635a8641SAndroid Build Coastguard Worker     const int kMessagesToSend = kMessageLimit * 120 / 100;
959*635a8641SAndroid Build Coastguard Worker     for (int i = 0; i < kMessagesToSend; ++i) {
960*635a8641SAndroid Build Coastguard Worker       if (!SendDouble(false, true))
961*635a8641SAndroid Build Coastguard Worker         break;
962*635a8641SAndroid Build Coastguard Worker     }
963*635a8641SAndroid Build Coastguard Worker     *answer = 42;
964*635a8641SAndroid Build Coastguard Worker     Done();
965*635a8641SAndroid Build Coastguard Worker   }
966*635a8641SAndroid Build Coastguard Worker };
967*635a8641SAndroid Build Coastguard Worker 
ChattyServer(bool pump_during_send)968*635a8641SAndroid Build Coastguard Worker void ChattyServer(bool pump_during_send) {
969*635a8641SAndroid Build Coastguard Worker   std::vector<Worker*> workers;
970*635a8641SAndroid Build Coastguard Worker   mojo::MessagePipe pipe;
971*635a8641SAndroid Build Coastguard Worker   workers.push_back(
972*635a8641SAndroid Build Coastguard Worker       new UnblockServer(pump_during_send, false, std::move(pipe.handle0)));
973*635a8641SAndroid Build Coastguard Worker   workers.push_back(new ChattyClient(std::move(pipe.handle1)));
974*635a8641SAndroid Build Coastguard Worker   RunTest(workers);
975*635a8641SAndroid Build Coastguard Worker }
976*635a8641SAndroid Build Coastguard Worker 
977*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
978*635a8641SAndroid Build Coastguard Worker // Times out.
979*635a8641SAndroid Build Coastguard Worker #define MAYBE_ChattyServer DISABLED_ChattyServer
980*635a8641SAndroid Build Coastguard Worker #else
981*635a8641SAndroid Build Coastguard Worker #define MAYBE_ChattyServer ChattyServer
982*635a8641SAndroid Build Coastguard Worker #endif
983*635a8641SAndroid Build Coastguard Worker // Tests http://b/1093251 - that sending lots of sync messages while
984*635a8641SAndroid Build Coastguard Worker // the receiver is waiting for a sync reply does not overflow the PostMessage
985*635a8641SAndroid Build Coastguard Worker // queue.
TEST_F(IPCSyncChannelTest,MAYBE_ChattyServer)986*635a8641SAndroid Build Coastguard Worker TEST_F(IPCSyncChannelTest, MAYBE_ChattyServer) {
987*635a8641SAndroid Build Coastguard Worker   ChattyServer(false);
988*635a8641SAndroid Build Coastguard Worker }
989*635a8641SAndroid Build Coastguard Worker 
990*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
991*635a8641SAndroid Build Coastguard Worker // Times out.
992*635a8641SAndroid Build Coastguard Worker #define MAYBE_ChattyServerPumpDuringSend DISABLED_ChattyServerPumpDuringSend
993*635a8641SAndroid Build Coastguard Worker #else
994*635a8641SAndroid Build Coastguard Worker #define MAYBE_ChattyServerPumpDuringSend ChattyServerPumpDuringSend
995*635a8641SAndroid Build Coastguard Worker #endif
TEST_F(IPCSyncChannelTest,MAYBE_ChattyServerPumpDuringSend)996*635a8641SAndroid Build Coastguard Worker TEST_F(IPCSyncChannelTest, MAYBE_ChattyServerPumpDuringSend) {
997*635a8641SAndroid Build Coastguard Worker   ChattyServer(true);
998*635a8641SAndroid Build Coastguard Worker }
999*635a8641SAndroid Build Coastguard Worker 
1000*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
1001*635a8641SAndroid Build Coastguard Worker 
NestedCallback(Worker * server)1002*635a8641SAndroid Build Coastguard Worker void NestedCallback(Worker* server) {
1003*635a8641SAndroid Build Coastguard Worker   // Sleep a bit so that we wake up after the reply has been received.
1004*635a8641SAndroid Build Coastguard Worker   base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(250));
1005*635a8641SAndroid Build Coastguard Worker   server->SendAnswerToLife(true, true);
1006*635a8641SAndroid Build Coastguard Worker }
1007*635a8641SAndroid Build Coastguard Worker 
1008*635a8641SAndroid Build Coastguard Worker bool timeout_occurred = false;
1009*635a8641SAndroid Build Coastguard Worker 
TimeoutCallback()1010*635a8641SAndroid Build Coastguard Worker void TimeoutCallback() {
1011*635a8641SAndroid Build Coastguard Worker   timeout_occurred = true;
1012*635a8641SAndroid Build Coastguard Worker }
1013*635a8641SAndroid Build Coastguard Worker 
1014*635a8641SAndroid Build Coastguard Worker class DoneEventRaceServer : public Worker {
1015*635a8641SAndroid Build Coastguard Worker  public:
DoneEventRaceServer(mojo::ScopedMessagePipeHandle channel_handle)1016*635a8641SAndroid Build Coastguard Worker   explicit DoneEventRaceServer(mojo::ScopedMessagePipeHandle channel_handle)
1017*635a8641SAndroid Build Coastguard Worker       : Worker(Channel::MODE_SERVER,
1018*635a8641SAndroid Build Coastguard Worker                "done_event_race_server",
1019*635a8641SAndroid Build Coastguard Worker                std::move(channel_handle)) {}
1020*635a8641SAndroid Build Coastguard Worker 
Run()1021*635a8641SAndroid Build Coastguard Worker   void Run() override {
1022*635a8641SAndroid Build Coastguard Worker     base::ThreadTaskRunnerHandle::Get()->PostTask(
1023*635a8641SAndroid Build Coastguard Worker         FROM_HERE, base::Bind(&NestedCallback, base::Unretained(this)));
1024*635a8641SAndroid Build Coastguard Worker     base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
1025*635a8641SAndroid Build Coastguard Worker         FROM_HERE, base::Bind(&TimeoutCallback),
1026*635a8641SAndroid Build Coastguard Worker         base::TimeDelta::FromSeconds(9));
1027*635a8641SAndroid Build Coastguard Worker     // Even though we have a timeout on the Send, it will succeed since for this
1028*635a8641SAndroid Build Coastguard Worker     // bug, the reply message comes back and is deserialized, however the done
1029*635a8641SAndroid Build Coastguard Worker     // event wasn't set.  So we indirectly use the timeout task to notice if a
1030*635a8641SAndroid Build Coastguard Worker     // timeout occurred.
1031*635a8641SAndroid Build Coastguard Worker     SendAnswerToLife(true, true);
1032*635a8641SAndroid Build Coastguard Worker     DCHECK(!timeout_occurred);
1033*635a8641SAndroid Build Coastguard Worker     Done();
1034*635a8641SAndroid Build Coastguard Worker   }
1035*635a8641SAndroid Build Coastguard Worker };
1036*635a8641SAndroid Build Coastguard Worker 
1037*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
1038*635a8641SAndroid Build Coastguard Worker #define MAYBE_DoneEventRace DISABLED_DoneEventRace
1039*635a8641SAndroid Build Coastguard Worker #else
1040*635a8641SAndroid Build Coastguard Worker #define MAYBE_DoneEventRace DoneEventRace
1041*635a8641SAndroid Build Coastguard Worker #endif
1042*635a8641SAndroid Build Coastguard Worker // Tests http://b/1474092 - that if after the done_event is set but before
1043*635a8641SAndroid Build Coastguard Worker // OnObjectSignaled is called another message is sent out, then after its
1044*635a8641SAndroid Build Coastguard Worker // reply comes back OnObjectSignaled will be called for the first message.
TEST_F(IPCSyncChannelTest,MAYBE_DoneEventRace)1045*635a8641SAndroid Build Coastguard Worker TEST_F(IPCSyncChannelTest, MAYBE_DoneEventRace) {
1046*635a8641SAndroid Build Coastguard Worker   std::vector<Worker*> workers;
1047*635a8641SAndroid Build Coastguard Worker   mojo::MessagePipe pipe;
1048*635a8641SAndroid Build Coastguard Worker   workers.push_back(new DoneEventRaceServer(std::move(pipe.handle0)));
1049*635a8641SAndroid Build Coastguard Worker   workers.push_back(new SimpleClient(std::move(pipe.handle1)));
1050*635a8641SAndroid Build Coastguard Worker   RunTest(workers);
1051*635a8641SAndroid Build Coastguard Worker }
1052*635a8641SAndroid Build Coastguard Worker 
1053*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
1054*635a8641SAndroid Build Coastguard Worker 
1055*635a8641SAndroid Build Coastguard Worker class TestSyncMessageFilter : public SyncMessageFilter {
1056*635a8641SAndroid Build Coastguard Worker  public:
TestSyncMessageFilter(base::WaitableEvent * shutdown_event,Worker * worker,scoped_refptr<base::SingleThreadTaskRunner> task_runner)1057*635a8641SAndroid Build Coastguard Worker   TestSyncMessageFilter(
1058*635a8641SAndroid Build Coastguard Worker       base::WaitableEvent* shutdown_event,
1059*635a8641SAndroid Build Coastguard Worker       Worker* worker,
1060*635a8641SAndroid Build Coastguard Worker       scoped_refptr<base::SingleThreadTaskRunner> task_runner)
1061*635a8641SAndroid Build Coastguard Worker       : SyncMessageFilter(shutdown_event),
1062*635a8641SAndroid Build Coastguard Worker         worker_(worker),
1063*635a8641SAndroid Build Coastguard Worker         task_runner_(task_runner) {}
1064*635a8641SAndroid Build Coastguard Worker 
OnFilterAdded(Channel * channel)1065*635a8641SAndroid Build Coastguard Worker   void OnFilterAdded(Channel* channel) override {
1066*635a8641SAndroid Build Coastguard Worker     SyncMessageFilter::OnFilterAdded(channel);
1067*635a8641SAndroid Build Coastguard Worker     task_runner_->PostTask(
1068*635a8641SAndroid Build Coastguard Worker         FROM_HERE,
1069*635a8641SAndroid Build Coastguard Worker         base::Bind(&TestSyncMessageFilter::SendMessageOnHelperThread, this));
1070*635a8641SAndroid Build Coastguard Worker   }
1071*635a8641SAndroid Build Coastguard Worker 
SendMessageOnHelperThread()1072*635a8641SAndroid Build Coastguard Worker   void SendMessageOnHelperThread() {
1073*635a8641SAndroid Build Coastguard Worker     int answer = 0;
1074*635a8641SAndroid Build Coastguard Worker     bool result = Send(new SyncChannelTestMsg_AnswerToLife(&answer));
1075*635a8641SAndroid Build Coastguard Worker     DCHECK(result);
1076*635a8641SAndroid Build Coastguard Worker     DCHECK_EQ(answer, 42);
1077*635a8641SAndroid Build Coastguard Worker 
1078*635a8641SAndroid Build Coastguard Worker     worker_->Done();
1079*635a8641SAndroid Build Coastguard Worker   }
1080*635a8641SAndroid Build Coastguard Worker 
1081*635a8641SAndroid Build Coastguard Worker  private:
1082*635a8641SAndroid Build Coastguard Worker   ~TestSyncMessageFilter() override = default;
1083*635a8641SAndroid Build Coastguard Worker 
1084*635a8641SAndroid Build Coastguard Worker   Worker* worker_;
1085*635a8641SAndroid Build Coastguard Worker   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
1086*635a8641SAndroid Build Coastguard Worker };
1087*635a8641SAndroid Build Coastguard Worker 
1088*635a8641SAndroid Build Coastguard Worker class SyncMessageFilterServer : public Worker {
1089*635a8641SAndroid Build Coastguard Worker  public:
SyncMessageFilterServer(mojo::ScopedMessagePipeHandle channel_handle)1090*635a8641SAndroid Build Coastguard Worker   explicit SyncMessageFilterServer(mojo::ScopedMessagePipeHandle channel_handle)
1091*635a8641SAndroid Build Coastguard Worker       : Worker(Channel::MODE_SERVER,
1092*635a8641SAndroid Build Coastguard Worker                "sync_message_filter_server",
1093*635a8641SAndroid Build Coastguard Worker                std::move(channel_handle)),
1094*635a8641SAndroid Build Coastguard Worker         thread_("helper_thread") {
1095*635a8641SAndroid Build Coastguard Worker     base::Thread::Options options;
1096*635a8641SAndroid Build Coastguard Worker     options.message_loop_type = base::MessageLoop::TYPE_DEFAULT;
1097*635a8641SAndroid Build Coastguard Worker     thread_.StartWithOptions(options);
1098*635a8641SAndroid Build Coastguard Worker     filter_ = new TestSyncMessageFilter(shutdown_event(), this,
1099*635a8641SAndroid Build Coastguard Worker                                         thread_.task_runner());
1100*635a8641SAndroid Build Coastguard Worker   }
1101*635a8641SAndroid Build Coastguard Worker 
Run()1102*635a8641SAndroid Build Coastguard Worker   void Run() override {
1103*635a8641SAndroid Build Coastguard Worker     channel()->AddFilter(filter_.get());
1104*635a8641SAndroid Build Coastguard Worker   }
1105*635a8641SAndroid Build Coastguard Worker 
1106*635a8641SAndroid Build Coastguard Worker   base::Thread thread_;
1107*635a8641SAndroid Build Coastguard Worker   scoped_refptr<TestSyncMessageFilter> filter_;
1108*635a8641SAndroid Build Coastguard Worker };
1109*635a8641SAndroid Build Coastguard Worker 
1110*635a8641SAndroid Build Coastguard Worker // This class provides functionality to test the case that a Send on the sync
1111*635a8641SAndroid Build Coastguard Worker // channel does not crash after the channel has been closed.
1112*635a8641SAndroid Build Coastguard Worker class ServerSendAfterClose : public Worker {
1113*635a8641SAndroid Build Coastguard Worker  public:
ServerSendAfterClose(mojo::ScopedMessagePipeHandle channel_handle)1114*635a8641SAndroid Build Coastguard Worker   explicit ServerSendAfterClose(mojo::ScopedMessagePipeHandle channel_handle)
1115*635a8641SAndroid Build Coastguard Worker       : Worker(Channel::MODE_SERVER,
1116*635a8641SAndroid Build Coastguard Worker                "simpler_server",
1117*635a8641SAndroid Build Coastguard Worker                std::move(channel_handle)),
1118*635a8641SAndroid Build Coastguard Worker         send_result_(true) {}
1119*635a8641SAndroid Build Coastguard Worker 
SendDummy()1120*635a8641SAndroid Build Coastguard Worker   bool SendDummy() {
1121*635a8641SAndroid Build Coastguard Worker     ListenerThread()->task_runner()->PostTask(
1122*635a8641SAndroid Build Coastguard Worker         FROM_HERE,
1123*635a8641SAndroid Build Coastguard Worker         base::Bind(base::IgnoreResult(&ServerSendAfterClose::Send),
1124*635a8641SAndroid Build Coastguard Worker                    base::Unretained(this), new SyncChannelTestMsg_NoArgs));
1125*635a8641SAndroid Build Coastguard Worker     return true;
1126*635a8641SAndroid Build Coastguard Worker   }
1127*635a8641SAndroid Build Coastguard Worker 
send_result() const1128*635a8641SAndroid Build Coastguard Worker   bool send_result() const {
1129*635a8641SAndroid Build Coastguard Worker     return send_result_;
1130*635a8641SAndroid Build Coastguard Worker   }
1131*635a8641SAndroid Build Coastguard Worker 
1132*635a8641SAndroid Build Coastguard Worker  private:
Run()1133*635a8641SAndroid Build Coastguard Worker   void Run() override {
1134*635a8641SAndroid Build Coastguard Worker     CloseChannel();
1135*635a8641SAndroid Build Coastguard Worker     Done();
1136*635a8641SAndroid Build Coastguard Worker   }
1137*635a8641SAndroid Build Coastguard Worker 
Send(Message * msg)1138*635a8641SAndroid Build Coastguard Worker   bool Send(Message* msg) override {
1139*635a8641SAndroid Build Coastguard Worker     send_result_ = Worker::Send(msg);
1140*635a8641SAndroid Build Coastguard Worker     Done();
1141*635a8641SAndroid Build Coastguard Worker     return send_result_;
1142*635a8641SAndroid Build Coastguard Worker   }
1143*635a8641SAndroid Build Coastguard Worker 
1144*635a8641SAndroid Build Coastguard Worker   bool send_result_;
1145*635a8641SAndroid Build Coastguard Worker };
1146*635a8641SAndroid Build Coastguard Worker 
1147*635a8641SAndroid Build Coastguard Worker // Tests basic synchronous call
TEST_F(IPCSyncChannelTest,SyncMessageFilter)1148*635a8641SAndroid Build Coastguard Worker TEST_F(IPCSyncChannelTest, SyncMessageFilter) {
1149*635a8641SAndroid Build Coastguard Worker   std::vector<Worker*> workers;
1150*635a8641SAndroid Build Coastguard Worker   mojo::MessagePipe pipe;
1151*635a8641SAndroid Build Coastguard Worker   workers.push_back(new SyncMessageFilterServer(std::move(pipe.handle0)));
1152*635a8641SAndroid Build Coastguard Worker   workers.push_back(new SimpleClient(std::move(pipe.handle1)));
1153*635a8641SAndroid Build Coastguard Worker   RunTest(workers);
1154*635a8641SAndroid Build Coastguard Worker }
1155*635a8641SAndroid Build Coastguard Worker 
1156*635a8641SAndroid Build Coastguard Worker // Test the case when the channel is closed and a Send is attempted after that.
TEST_F(IPCSyncChannelTest,SendAfterClose)1157*635a8641SAndroid Build Coastguard Worker TEST_F(IPCSyncChannelTest, SendAfterClose) {
1158*635a8641SAndroid Build Coastguard Worker   mojo::MessagePipe pipe;
1159*635a8641SAndroid Build Coastguard Worker   ServerSendAfterClose server(std::move(pipe.handle0));
1160*635a8641SAndroid Build Coastguard Worker   server.Start();
1161*635a8641SAndroid Build Coastguard Worker 
1162*635a8641SAndroid Build Coastguard Worker   server.done_event()->Wait();
1163*635a8641SAndroid Build Coastguard Worker   server.done_event()->Reset();
1164*635a8641SAndroid Build Coastguard Worker 
1165*635a8641SAndroid Build Coastguard Worker   server.SendDummy();
1166*635a8641SAndroid Build Coastguard Worker   server.done_event()->Wait();
1167*635a8641SAndroid Build Coastguard Worker 
1168*635a8641SAndroid Build Coastguard Worker   EXPECT_FALSE(server.send_result());
1169*635a8641SAndroid Build Coastguard Worker 
1170*635a8641SAndroid Build Coastguard Worker   server.Shutdown();
1171*635a8641SAndroid Build Coastguard Worker }
1172*635a8641SAndroid Build Coastguard Worker 
1173*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
1174*635a8641SAndroid Build Coastguard Worker 
1175*635a8641SAndroid Build Coastguard Worker class RestrictedDispatchServer : public Worker {
1176*635a8641SAndroid Build Coastguard Worker  public:
RestrictedDispatchServer(WaitableEvent * sent_ping_event,WaitableEvent * wait_event,mojo::ScopedMessagePipeHandle channel_handle)1177*635a8641SAndroid Build Coastguard Worker   RestrictedDispatchServer(WaitableEvent* sent_ping_event,
1178*635a8641SAndroid Build Coastguard Worker                            WaitableEvent* wait_event,
1179*635a8641SAndroid Build Coastguard Worker                            mojo::ScopedMessagePipeHandle channel_handle)
1180*635a8641SAndroid Build Coastguard Worker       : Worker(std::move(channel_handle), Channel::MODE_SERVER),
1181*635a8641SAndroid Build Coastguard Worker         sent_ping_event_(sent_ping_event),
1182*635a8641SAndroid Build Coastguard Worker         wait_event_(wait_event) {}
1183*635a8641SAndroid Build Coastguard Worker 
OnDoPing(int ping)1184*635a8641SAndroid Build Coastguard Worker   void OnDoPing(int ping) {
1185*635a8641SAndroid Build Coastguard Worker     // Send an asynchronous message that unblocks the caller.
1186*635a8641SAndroid Build Coastguard Worker     Message* msg = new SyncChannelTestMsg_Ping(ping);
1187*635a8641SAndroid Build Coastguard Worker     msg->set_unblock(true);
1188*635a8641SAndroid Build Coastguard Worker     Send(msg);
1189*635a8641SAndroid Build Coastguard Worker     // Signal the event after the message has been sent on the channel, on the
1190*635a8641SAndroid Build Coastguard Worker     // IPC thread.
1191*635a8641SAndroid Build Coastguard Worker     ipc_thread().task_runner()->PostTask(
1192*635a8641SAndroid Build Coastguard Worker         FROM_HERE, base::Bind(&RestrictedDispatchServer::OnPingSent,
1193*635a8641SAndroid Build Coastguard Worker                               base::Unretained(this)));
1194*635a8641SAndroid Build Coastguard Worker   }
1195*635a8641SAndroid Build Coastguard Worker 
OnPingTTL(int ping,int * out)1196*635a8641SAndroid Build Coastguard Worker   void OnPingTTL(int ping, int* out) {
1197*635a8641SAndroid Build Coastguard Worker     *out = ping;
1198*635a8641SAndroid Build Coastguard Worker     wait_event_->Wait();
1199*635a8641SAndroid Build Coastguard Worker   }
1200*635a8641SAndroid Build Coastguard Worker 
ListenerThread()1201*635a8641SAndroid Build Coastguard Worker   base::Thread* ListenerThread() { return Worker::ListenerThread(); }
1202*635a8641SAndroid Build Coastguard Worker 
1203*635a8641SAndroid Build Coastguard Worker  private:
OnMessageReceived(const Message & message)1204*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const Message& message) override {
1205*635a8641SAndroid Build Coastguard Worker     IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchServer, message)
1206*635a8641SAndroid Build Coastguard Worker      IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs)
1207*635a8641SAndroid Build Coastguard Worker      IPC_MESSAGE_HANDLER(SyncChannelTestMsg_PingTTL, OnPingTTL)
1208*635a8641SAndroid Build Coastguard Worker      IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, Done)
1209*635a8641SAndroid Build Coastguard Worker     IPC_END_MESSAGE_MAP()
1210*635a8641SAndroid Build Coastguard Worker     return true;
1211*635a8641SAndroid Build Coastguard Worker   }
1212*635a8641SAndroid Build Coastguard Worker 
OnPingSent()1213*635a8641SAndroid Build Coastguard Worker   void OnPingSent() {
1214*635a8641SAndroid Build Coastguard Worker     sent_ping_event_->Signal();
1215*635a8641SAndroid Build Coastguard Worker   }
1216*635a8641SAndroid Build Coastguard Worker 
OnNoArgs()1217*635a8641SAndroid Build Coastguard Worker   void OnNoArgs() { }
1218*635a8641SAndroid Build Coastguard Worker   WaitableEvent* sent_ping_event_;
1219*635a8641SAndroid Build Coastguard Worker   WaitableEvent* wait_event_;
1220*635a8641SAndroid Build Coastguard Worker };
1221*635a8641SAndroid Build Coastguard Worker 
1222*635a8641SAndroid Build Coastguard Worker class NonRestrictedDispatchServer : public Worker {
1223*635a8641SAndroid Build Coastguard Worker  public:
NonRestrictedDispatchServer(WaitableEvent * signal_event,mojo::ScopedMessagePipeHandle channel_handle)1224*635a8641SAndroid Build Coastguard Worker   NonRestrictedDispatchServer(WaitableEvent* signal_event,
1225*635a8641SAndroid Build Coastguard Worker                               mojo::ScopedMessagePipeHandle channel_handle)
1226*635a8641SAndroid Build Coastguard Worker       : Worker(std::move(channel_handle), Channel::MODE_SERVER),
1227*635a8641SAndroid Build Coastguard Worker         signal_event_(signal_event) {}
1228*635a8641SAndroid Build Coastguard Worker 
ListenerThread()1229*635a8641SAndroid Build Coastguard Worker   base::Thread* ListenerThread() { return Worker::ListenerThread(); }
1230*635a8641SAndroid Build Coastguard Worker 
OnDoPingTTL(int ping)1231*635a8641SAndroid Build Coastguard Worker   void OnDoPingTTL(int ping) {
1232*635a8641SAndroid Build Coastguard Worker     int value = 0;
1233*635a8641SAndroid Build Coastguard Worker     Send(new SyncChannelTestMsg_PingTTL(ping, &value));
1234*635a8641SAndroid Build Coastguard Worker     signal_event_->Signal();
1235*635a8641SAndroid Build Coastguard Worker   }
1236*635a8641SAndroid Build Coastguard Worker 
1237*635a8641SAndroid Build Coastguard Worker  private:
OnMessageReceived(const Message & message)1238*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const Message& message) override {
1239*635a8641SAndroid Build Coastguard Worker     IPC_BEGIN_MESSAGE_MAP(NonRestrictedDispatchServer, message)
1240*635a8641SAndroid Build Coastguard Worker      IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs)
1241*635a8641SAndroid Build Coastguard Worker      IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, Done)
1242*635a8641SAndroid Build Coastguard Worker     IPC_END_MESSAGE_MAP()
1243*635a8641SAndroid Build Coastguard Worker     return true;
1244*635a8641SAndroid Build Coastguard Worker   }
1245*635a8641SAndroid Build Coastguard Worker 
OnNoArgs()1246*635a8641SAndroid Build Coastguard Worker   void OnNoArgs() { }
1247*635a8641SAndroid Build Coastguard Worker   WaitableEvent* signal_event_;
1248*635a8641SAndroid Build Coastguard Worker };
1249*635a8641SAndroid Build Coastguard Worker 
1250*635a8641SAndroid Build Coastguard Worker class RestrictedDispatchClient : public Worker {
1251*635a8641SAndroid Build Coastguard Worker  public:
RestrictedDispatchClient(WaitableEvent * sent_ping_event,RestrictedDispatchServer * server,NonRestrictedDispatchServer * server2,int * success,mojo::ScopedMessagePipeHandle restricted_channel_handle,mojo::ScopedMessagePipeHandle non_restricted_channel_handle)1252*635a8641SAndroid Build Coastguard Worker   RestrictedDispatchClient(
1253*635a8641SAndroid Build Coastguard Worker       WaitableEvent* sent_ping_event,
1254*635a8641SAndroid Build Coastguard Worker       RestrictedDispatchServer* server,
1255*635a8641SAndroid Build Coastguard Worker       NonRestrictedDispatchServer* server2,
1256*635a8641SAndroid Build Coastguard Worker       int* success,
1257*635a8641SAndroid Build Coastguard Worker       mojo::ScopedMessagePipeHandle restricted_channel_handle,
1258*635a8641SAndroid Build Coastguard Worker       mojo::ScopedMessagePipeHandle non_restricted_channel_handle)
1259*635a8641SAndroid Build Coastguard Worker       : Worker(std::move(restricted_channel_handle), Channel::MODE_CLIENT),
1260*635a8641SAndroid Build Coastguard Worker         ping_(0),
1261*635a8641SAndroid Build Coastguard Worker         server_(server),
1262*635a8641SAndroid Build Coastguard Worker         server2_(server2),
1263*635a8641SAndroid Build Coastguard Worker         success_(success),
1264*635a8641SAndroid Build Coastguard Worker         sent_ping_event_(sent_ping_event),
1265*635a8641SAndroid Build Coastguard Worker         non_restricted_channel_handle_(
1266*635a8641SAndroid Build Coastguard Worker             std::move(non_restricted_channel_handle)) {}
1267*635a8641SAndroid Build Coastguard Worker 
Run()1268*635a8641SAndroid Build Coastguard Worker   void Run() override {
1269*635a8641SAndroid Build Coastguard Worker     // Incoming messages from our channel should only be dispatched when we
1270*635a8641SAndroid Build Coastguard Worker     // send a message on that same channel.
1271*635a8641SAndroid Build Coastguard Worker     channel()->SetRestrictDispatchChannelGroup(1);
1272*635a8641SAndroid Build Coastguard Worker 
1273*635a8641SAndroid Build Coastguard Worker     server_->ListenerThread()->task_runner()->PostTask(
1274*635a8641SAndroid Build Coastguard Worker         FROM_HERE, base::Bind(&RestrictedDispatchServer::OnDoPing,
1275*635a8641SAndroid Build Coastguard Worker                               base::Unretained(server_), 1));
1276*635a8641SAndroid Build Coastguard Worker     sent_ping_event_->Wait();
1277*635a8641SAndroid Build Coastguard Worker     Send(new SyncChannelTestMsg_NoArgs);
1278*635a8641SAndroid Build Coastguard Worker     if (ping_ == 1)
1279*635a8641SAndroid Build Coastguard Worker       ++*success_;
1280*635a8641SAndroid Build Coastguard Worker     else
1281*635a8641SAndroid Build Coastguard Worker       LOG(ERROR) << "Send failed to dispatch incoming message on same channel";
1282*635a8641SAndroid Build Coastguard Worker 
1283*635a8641SAndroid Build Coastguard Worker     non_restricted_channel_ = SyncChannel::Create(
1284*635a8641SAndroid Build Coastguard Worker         non_restricted_channel_handle_.release(), IPC::Channel::MODE_CLIENT,
1285*635a8641SAndroid Build Coastguard Worker         this, ipc_thread().task_runner(), base::ThreadTaskRunnerHandle::Get(),
1286*635a8641SAndroid Build Coastguard Worker         true, shutdown_event());
1287*635a8641SAndroid Build Coastguard Worker 
1288*635a8641SAndroid Build Coastguard Worker     server_->ListenerThread()->task_runner()->PostTask(
1289*635a8641SAndroid Build Coastguard Worker         FROM_HERE, base::Bind(&RestrictedDispatchServer::OnDoPing,
1290*635a8641SAndroid Build Coastguard Worker                               base::Unretained(server_), 2));
1291*635a8641SAndroid Build Coastguard Worker     sent_ping_event_->Wait();
1292*635a8641SAndroid Build Coastguard Worker     // Check that the incoming message is *not* dispatched when sending on the
1293*635a8641SAndroid Build Coastguard Worker     // non restricted channel.
1294*635a8641SAndroid Build Coastguard Worker     // TODO(piman): there is a possibility of a false positive race condition
1295*635a8641SAndroid Build Coastguard Worker     // here, if the message that was posted on the server-side end of the pipe
1296*635a8641SAndroid Build Coastguard Worker     // is not visible yet on the client side, but I don't know how to solve this
1297*635a8641SAndroid Build Coastguard Worker     // without hooking into the internals of SyncChannel. I haven't seen it in
1298*635a8641SAndroid Build Coastguard Worker     // practice (i.e. not setting SetRestrictDispatchToSameChannel does cause
1299*635a8641SAndroid Build Coastguard Worker     // the following to fail).
1300*635a8641SAndroid Build Coastguard Worker     non_restricted_channel_->Send(new SyncChannelTestMsg_NoArgs);
1301*635a8641SAndroid Build Coastguard Worker     if (ping_ == 1)
1302*635a8641SAndroid Build Coastguard Worker       ++*success_;
1303*635a8641SAndroid Build Coastguard Worker     else
1304*635a8641SAndroid Build Coastguard Worker       LOG(ERROR) << "Send dispatched message from restricted channel";
1305*635a8641SAndroid Build Coastguard Worker 
1306*635a8641SAndroid Build Coastguard Worker     Send(new SyncChannelTestMsg_NoArgs);
1307*635a8641SAndroid Build Coastguard Worker     if (ping_ == 2)
1308*635a8641SAndroid Build Coastguard Worker       ++*success_;
1309*635a8641SAndroid Build Coastguard Worker     else
1310*635a8641SAndroid Build Coastguard Worker       LOG(ERROR) << "Send failed to dispatch incoming message on same channel";
1311*635a8641SAndroid Build Coastguard Worker 
1312*635a8641SAndroid Build Coastguard Worker     // Check that the incoming message on the non-restricted channel is
1313*635a8641SAndroid Build Coastguard Worker     // dispatched when sending on the restricted channel.
1314*635a8641SAndroid Build Coastguard Worker     server2_->ListenerThread()->task_runner()->PostTask(
1315*635a8641SAndroid Build Coastguard Worker         FROM_HERE, base::Bind(&NonRestrictedDispatchServer::OnDoPingTTL,
1316*635a8641SAndroid Build Coastguard Worker                               base::Unretained(server2_), 3));
1317*635a8641SAndroid Build Coastguard Worker     int value = 0;
1318*635a8641SAndroid Build Coastguard Worker     Send(new SyncChannelTestMsg_PingTTL(4, &value));
1319*635a8641SAndroid Build Coastguard Worker     if (ping_ == 3 && value == 4)
1320*635a8641SAndroid Build Coastguard Worker       ++*success_;
1321*635a8641SAndroid Build Coastguard Worker     else
1322*635a8641SAndroid Build Coastguard Worker       LOG(ERROR) << "Send failed to dispatch message from unrestricted channel";
1323*635a8641SAndroid Build Coastguard Worker 
1324*635a8641SAndroid Build Coastguard Worker     non_restricted_channel_->Send(new SyncChannelTestMsg_Done);
1325*635a8641SAndroid Build Coastguard Worker     non_restricted_channel_.reset();
1326*635a8641SAndroid Build Coastguard Worker     Send(new SyncChannelTestMsg_Done);
1327*635a8641SAndroid Build Coastguard Worker     Done();
1328*635a8641SAndroid Build Coastguard Worker   }
1329*635a8641SAndroid Build Coastguard Worker 
1330*635a8641SAndroid Build Coastguard Worker  private:
OnMessageReceived(const Message & message)1331*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const Message& message) override {
1332*635a8641SAndroid Build Coastguard Worker     IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchClient, message)
1333*635a8641SAndroid Build Coastguard Worker      IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Ping, OnPing)
1334*635a8641SAndroid Build Coastguard Worker      IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_PingTTL, OnPingTTL)
1335*635a8641SAndroid Build Coastguard Worker     IPC_END_MESSAGE_MAP()
1336*635a8641SAndroid Build Coastguard Worker     return true;
1337*635a8641SAndroid Build Coastguard Worker   }
1338*635a8641SAndroid Build Coastguard Worker 
OnPing(int ping)1339*635a8641SAndroid Build Coastguard Worker   void OnPing(int ping) {
1340*635a8641SAndroid Build Coastguard Worker     ping_ = ping;
1341*635a8641SAndroid Build Coastguard Worker   }
1342*635a8641SAndroid Build Coastguard Worker 
OnPingTTL(int ping,IPC::Message * reply)1343*635a8641SAndroid Build Coastguard Worker   void OnPingTTL(int ping, IPC::Message* reply) {
1344*635a8641SAndroid Build Coastguard Worker     ping_ = ping;
1345*635a8641SAndroid Build Coastguard Worker     // This message comes from the NonRestrictedDispatchServer, we have to send
1346*635a8641SAndroid Build Coastguard Worker     // the reply back manually.
1347*635a8641SAndroid Build Coastguard Worker     SyncChannelTestMsg_PingTTL::WriteReplyParams(reply, ping);
1348*635a8641SAndroid Build Coastguard Worker     non_restricted_channel_->Send(reply);
1349*635a8641SAndroid Build Coastguard Worker   }
1350*635a8641SAndroid Build Coastguard Worker 
1351*635a8641SAndroid Build Coastguard Worker   int ping_;
1352*635a8641SAndroid Build Coastguard Worker   RestrictedDispatchServer* server_;
1353*635a8641SAndroid Build Coastguard Worker   NonRestrictedDispatchServer* server2_;
1354*635a8641SAndroid Build Coastguard Worker   int* success_;
1355*635a8641SAndroid Build Coastguard Worker   WaitableEvent* sent_ping_event_;
1356*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<SyncChannel> non_restricted_channel_;
1357*635a8641SAndroid Build Coastguard Worker   mojo::ScopedMessagePipeHandle non_restricted_channel_handle_;
1358*635a8641SAndroid Build Coastguard Worker };
1359*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCSyncChannelTest,RestrictedDispatch)1360*635a8641SAndroid Build Coastguard Worker TEST_F(IPCSyncChannelTest, RestrictedDispatch) {
1361*635a8641SAndroid Build Coastguard Worker   WaitableEvent sent_ping_event(
1362*635a8641SAndroid Build Coastguard Worker       base::WaitableEvent::ResetPolicy::AUTOMATIC,
1363*635a8641SAndroid Build Coastguard Worker       base::WaitableEvent::InitialState::NOT_SIGNALED);
1364*635a8641SAndroid Build Coastguard Worker   WaitableEvent wait_event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
1365*635a8641SAndroid Build Coastguard Worker                            base::WaitableEvent::InitialState::NOT_SIGNALED);
1366*635a8641SAndroid Build Coastguard Worker   mojo::MessagePipe restricted_pipe, non_restricted_pipe;
1367*635a8641SAndroid Build Coastguard Worker   RestrictedDispatchServer* server = new RestrictedDispatchServer(
1368*635a8641SAndroid Build Coastguard Worker       &sent_ping_event, &wait_event, std::move(restricted_pipe.handle0));
1369*635a8641SAndroid Build Coastguard Worker   NonRestrictedDispatchServer* server2 = new NonRestrictedDispatchServer(
1370*635a8641SAndroid Build Coastguard Worker       &wait_event, std::move(non_restricted_pipe.handle0));
1371*635a8641SAndroid Build Coastguard Worker 
1372*635a8641SAndroid Build Coastguard Worker   int success = 0;
1373*635a8641SAndroid Build Coastguard Worker   std::vector<Worker*> workers;
1374*635a8641SAndroid Build Coastguard Worker   workers.push_back(server);
1375*635a8641SAndroid Build Coastguard Worker   workers.push_back(server2);
1376*635a8641SAndroid Build Coastguard Worker   workers.push_back(
1377*635a8641SAndroid Build Coastguard Worker       new RestrictedDispatchClient(&sent_ping_event, server, server2, &success,
1378*635a8641SAndroid Build Coastguard Worker                                    std::move(restricted_pipe.handle1),
1379*635a8641SAndroid Build Coastguard Worker                                    std::move(non_restricted_pipe.handle1)));
1380*635a8641SAndroid Build Coastguard Worker   RunTest(workers);
1381*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(4, success);
1382*635a8641SAndroid Build Coastguard Worker }
1383*635a8641SAndroid Build Coastguard Worker 
1384*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
1385*635a8641SAndroid Build Coastguard Worker 
1386*635a8641SAndroid Build Coastguard Worker // This test case inspired by crbug.com/108491
1387*635a8641SAndroid Build Coastguard Worker // We create two servers that use the same ListenerThread but have
1388*635a8641SAndroid Build Coastguard Worker // SetRestrictDispatchToSameChannel set to true.
1389*635a8641SAndroid Build Coastguard Worker // We create clients, then use some specific WaitableEvent wait/signalling to
1390*635a8641SAndroid Build Coastguard Worker // ensure that messages get dispatched in a way that causes a deadlock due to
1391*635a8641SAndroid Build Coastguard Worker // a nested dispatch and an eligible message in a higher-level dispatch's
1392*635a8641SAndroid Build Coastguard Worker // delayed_queue. Specifically, we start with client1 about so send an
1393*635a8641SAndroid Build Coastguard Worker // unblocking message to server1, while the shared listener thread for the
1394*635a8641SAndroid Build Coastguard Worker // servers server1 and server2 is about to send a non-unblocking message to
1395*635a8641SAndroid Build Coastguard Worker // client1. At the same time, client2 will be about to send an unblocking
1396*635a8641SAndroid Build Coastguard Worker // message to server2. Server1 will handle the client1->server1 message by
1397*635a8641SAndroid Build Coastguard Worker // telling server2 to send a non-unblocking message to client2.
1398*635a8641SAndroid Build Coastguard Worker // What should happen is that the send to server2 should find the pending,
1399*635a8641SAndroid Build Coastguard Worker // same-context client2->server2 message to dispatch, causing client2 to
1400*635a8641SAndroid Build Coastguard Worker // unblock then handle the server2->client2 message, so that the shared
1401*635a8641SAndroid Build Coastguard Worker // servers' listener thread can then respond to the client1->server1 message.
1402*635a8641SAndroid Build Coastguard Worker // Then client1 can handle the non-unblocking server1->client1 message.
1403*635a8641SAndroid Build Coastguard Worker // The old code would end up in a state where the server2->client2 message is
1404*635a8641SAndroid Build Coastguard Worker // sent, but the client2->server2 message (which is eligible for dispatch, and
1405*635a8641SAndroid Build Coastguard Worker // which is what client2 is waiting for) is stashed in a local delayed_queue
1406*635a8641SAndroid Build Coastguard Worker // that has server1's channel context, causing a deadlock.
1407*635a8641SAndroid Build Coastguard Worker // WaitableEvents in the events array are used to:
1408*635a8641SAndroid Build Coastguard Worker //   event 0: indicate to client1 that server listener is in OnDoServerTask
1409*635a8641SAndroid Build Coastguard Worker //   event 1: indicate to client1 that client2 listener is in OnDoClient2Task
1410*635a8641SAndroid Build Coastguard Worker //   event 2: indicate to server1 that client2 listener is in OnDoClient2Task
1411*635a8641SAndroid Build Coastguard Worker //   event 3: indicate to client2 that server listener is in OnDoServerTask
1412*635a8641SAndroid Build Coastguard Worker 
1413*635a8641SAndroid Build Coastguard Worker class RestrictedDispatchDeadlockServer : public Worker {
1414*635a8641SAndroid Build Coastguard Worker  public:
RestrictedDispatchDeadlockServer(int server_num,WaitableEvent * server_ready_event,WaitableEvent ** events,RestrictedDispatchDeadlockServer * peer,mojo::ScopedMessagePipeHandle channel_handle)1415*635a8641SAndroid Build Coastguard Worker   RestrictedDispatchDeadlockServer(int server_num,
1416*635a8641SAndroid Build Coastguard Worker                                    WaitableEvent* server_ready_event,
1417*635a8641SAndroid Build Coastguard Worker                                    WaitableEvent** events,
1418*635a8641SAndroid Build Coastguard Worker                                    RestrictedDispatchDeadlockServer* peer,
1419*635a8641SAndroid Build Coastguard Worker                                    mojo::ScopedMessagePipeHandle channel_handle)
1420*635a8641SAndroid Build Coastguard Worker       : Worker(std::move(channel_handle), Channel::MODE_SERVER),
1421*635a8641SAndroid Build Coastguard Worker         server_num_(server_num),
1422*635a8641SAndroid Build Coastguard Worker         server_ready_event_(server_ready_event),
1423*635a8641SAndroid Build Coastguard Worker         events_(events),
1424*635a8641SAndroid Build Coastguard Worker         peer_(peer) {}
1425*635a8641SAndroid Build Coastguard Worker 
OnDoServerTask()1426*635a8641SAndroid Build Coastguard Worker   void OnDoServerTask() {
1427*635a8641SAndroid Build Coastguard Worker     events_[3]->Signal();
1428*635a8641SAndroid Build Coastguard Worker     events_[2]->Wait();
1429*635a8641SAndroid Build Coastguard Worker     events_[0]->Signal();
1430*635a8641SAndroid Build Coastguard Worker     SendMessageToClient();
1431*635a8641SAndroid Build Coastguard Worker   }
1432*635a8641SAndroid Build Coastguard Worker 
Run()1433*635a8641SAndroid Build Coastguard Worker   void Run() override {
1434*635a8641SAndroid Build Coastguard Worker     channel()->SetRestrictDispatchChannelGroup(1);
1435*635a8641SAndroid Build Coastguard Worker     server_ready_event_->Signal();
1436*635a8641SAndroid Build Coastguard Worker   }
1437*635a8641SAndroid Build Coastguard Worker 
ListenerThread()1438*635a8641SAndroid Build Coastguard Worker   base::Thread* ListenerThread() { return Worker::ListenerThread(); }
1439*635a8641SAndroid Build Coastguard Worker 
1440*635a8641SAndroid Build Coastguard Worker  private:
OnMessageReceived(const Message & message)1441*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const Message& message) override {
1442*635a8641SAndroid Build Coastguard Worker     IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchDeadlockServer, message)
1443*635a8641SAndroid Build Coastguard Worker      IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs)
1444*635a8641SAndroid Build Coastguard Worker      IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, Done)
1445*635a8641SAndroid Build Coastguard Worker     IPC_END_MESSAGE_MAP()
1446*635a8641SAndroid Build Coastguard Worker     return true;
1447*635a8641SAndroid Build Coastguard Worker   }
1448*635a8641SAndroid Build Coastguard Worker 
OnNoArgs()1449*635a8641SAndroid Build Coastguard Worker   void OnNoArgs() {
1450*635a8641SAndroid Build Coastguard Worker     if (server_num_ == 1) {
1451*635a8641SAndroid Build Coastguard Worker       DCHECK(peer_ != NULL);
1452*635a8641SAndroid Build Coastguard Worker       peer_->SendMessageToClient();
1453*635a8641SAndroid Build Coastguard Worker     }
1454*635a8641SAndroid Build Coastguard Worker   }
1455*635a8641SAndroid Build Coastguard Worker 
SendMessageToClient()1456*635a8641SAndroid Build Coastguard Worker   void SendMessageToClient() {
1457*635a8641SAndroid Build Coastguard Worker     Message* msg = new SyncChannelTestMsg_NoArgs;
1458*635a8641SAndroid Build Coastguard Worker     msg->set_unblock(false);
1459*635a8641SAndroid Build Coastguard Worker     DCHECK(!msg->should_unblock());
1460*635a8641SAndroid Build Coastguard Worker     Send(msg);
1461*635a8641SAndroid Build Coastguard Worker   }
1462*635a8641SAndroid Build Coastguard Worker 
1463*635a8641SAndroid Build Coastguard Worker   int server_num_;
1464*635a8641SAndroid Build Coastguard Worker   WaitableEvent* server_ready_event_;
1465*635a8641SAndroid Build Coastguard Worker   WaitableEvent** events_;
1466*635a8641SAndroid Build Coastguard Worker   RestrictedDispatchDeadlockServer* peer_;
1467*635a8641SAndroid Build Coastguard Worker };
1468*635a8641SAndroid Build Coastguard Worker 
1469*635a8641SAndroid Build Coastguard Worker class RestrictedDispatchDeadlockClient2 : public Worker {
1470*635a8641SAndroid Build Coastguard Worker  public:
RestrictedDispatchDeadlockClient2(RestrictedDispatchDeadlockServer * server,WaitableEvent * server_ready_event,WaitableEvent ** events,mojo::ScopedMessagePipeHandle channel_handle)1471*635a8641SAndroid Build Coastguard Worker   RestrictedDispatchDeadlockClient2(
1472*635a8641SAndroid Build Coastguard Worker       RestrictedDispatchDeadlockServer* server,
1473*635a8641SAndroid Build Coastguard Worker       WaitableEvent* server_ready_event,
1474*635a8641SAndroid Build Coastguard Worker       WaitableEvent** events,
1475*635a8641SAndroid Build Coastguard Worker       mojo::ScopedMessagePipeHandle channel_handle)
1476*635a8641SAndroid Build Coastguard Worker       : Worker(std::move(channel_handle), Channel::MODE_CLIENT),
1477*635a8641SAndroid Build Coastguard Worker         server_ready_event_(server_ready_event),
1478*635a8641SAndroid Build Coastguard Worker         events_(events),
1479*635a8641SAndroid Build Coastguard Worker         received_msg_(false),
1480*635a8641SAndroid Build Coastguard Worker         received_noarg_reply_(false),
1481*635a8641SAndroid Build Coastguard Worker         done_issued_(false) {}
1482*635a8641SAndroid Build Coastguard Worker 
Run()1483*635a8641SAndroid Build Coastguard Worker   void Run() override {
1484*635a8641SAndroid Build Coastguard Worker     server_ready_event_->Wait();
1485*635a8641SAndroid Build Coastguard Worker   }
1486*635a8641SAndroid Build Coastguard Worker 
OnDoClient2Task()1487*635a8641SAndroid Build Coastguard Worker   void OnDoClient2Task() {
1488*635a8641SAndroid Build Coastguard Worker     events_[3]->Wait();
1489*635a8641SAndroid Build Coastguard Worker     events_[1]->Signal();
1490*635a8641SAndroid Build Coastguard Worker     events_[2]->Signal();
1491*635a8641SAndroid Build Coastguard Worker     DCHECK(received_msg_ == false);
1492*635a8641SAndroid Build Coastguard Worker 
1493*635a8641SAndroid Build Coastguard Worker     Message* message = new SyncChannelTestMsg_NoArgs;
1494*635a8641SAndroid Build Coastguard Worker     message->set_unblock(true);
1495*635a8641SAndroid Build Coastguard Worker     Send(message);
1496*635a8641SAndroid Build Coastguard Worker     received_noarg_reply_ = true;
1497*635a8641SAndroid Build Coastguard Worker   }
1498*635a8641SAndroid Build Coastguard Worker 
ListenerThread()1499*635a8641SAndroid Build Coastguard Worker   base::Thread* ListenerThread() { return Worker::ListenerThread(); }
1500*635a8641SAndroid Build Coastguard Worker  private:
OnMessageReceived(const Message & message)1501*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const Message& message) override {
1502*635a8641SAndroid Build Coastguard Worker     IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchDeadlockClient2, message)
1503*635a8641SAndroid Build Coastguard Worker      IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs)
1504*635a8641SAndroid Build Coastguard Worker     IPC_END_MESSAGE_MAP()
1505*635a8641SAndroid Build Coastguard Worker     return true;
1506*635a8641SAndroid Build Coastguard Worker   }
1507*635a8641SAndroid Build Coastguard Worker 
OnNoArgs()1508*635a8641SAndroid Build Coastguard Worker   void OnNoArgs() {
1509*635a8641SAndroid Build Coastguard Worker     received_msg_ = true;
1510*635a8641SAndroid Build Coastguard Worker     PossiblyDone();
1511*635a8641SAndroid Build Coastguard Worker   }
1512*635a8641SAndroid Build Coastguard Worker 
PossiblyDone()1513*635a8641SAndroid Build Coastguard Worker   void PossiblyDone() {
1514*635a8641SAndroid Build Coastguard Worker     if (received_noarg_reply_ && received_msg_) {
1515*635a8641SAndroid Build Coastguard Worker       DCHECK(done_issued_ == false);
1516*635a8641SAndroid Build Coastguard Worker       done_issued_ = true;
1517*635a8641SAndroid Build Coastguard Worker       Send(new SyncChannelTestMsg_Done);
1518*635a8641SAndroid Build Coastguard Worker       Done();
1519*635a8641SAndroid Build Coastguard Worker     }
1520*635a8641SAndroid Build Coastguard Worker   }
1521*635a8641SAndroid Build Coastguard Worker 
1522*635a8641SAndroid Build Coastguard Worker   WaitableEvent* server_ready_event_;
1523*635a8641SAndroid Build Coastguard Worker   WaitableEvent** events_;
1524*635a8641SAndroid Build Coastguard Worker   bool received_msg_;
1525*635a8641SAndroid Build Coastguard Worker   bool received_noarg_reply_;
1526*635a8641SAndroid Build Coastguard Worker   bool done_issued_;
1527*635a8641SAndroid Build Coastguard Worker };
1528*635a8641SAndroid Build Coastguard Worker 
1529*635a8641SAndroid Build Coastguard Worker class RestrictedDispatchDeadlockClient1 : public Worker {
1530*635a8641SAndroid Build Coastguard Worker  public:
RestrictedDispatchDeadlockClient1(RestrictedDispatchDeadlockServer * server,RestrictedDispatchDeadlockClient2 * peer,WaitableEvent * server_ready_event,WaitableEvent ** events,mojo::ScopedMessagePipeHandle channel_handle)1531*635a8641SAndroid Build Coastguard Worker   RestrictedDispatchDeadlockClient1(
1532*635a8641SAndroid Build Coastguard Worker       RestrictedDispatchDeadlockServer* server,
1533*635a8641SAndroid Build Coastguard Worker       RestrictedDispatchDeadlockClient2* peer,
1534*635a8641SAndroid Build Coastguard Worker       WaitableEvent* server_ready_event,
1535*635a8641SAndroid Build Coastguard Worker       WaitableEvent** events,
1536*635a8641SAndroid Build Coastguard Worker       mojo::ScopedMessagePipeHandle channel_handle)
1537*635a8641SAndroid Build Coastguard Worker       : Worker(std::move(channel_handle), Channel::MODE_CLIENT),
1538*635a8641SAndroid Build Coastguard Worker         server_(server),
1539*635a8641SAndroid Build Coastguard Worker         peer_(peer),
1540*635a8641SAndroid Build Coastguard Worker         server_ready_event_(server_ready_event),
1541*635a8641SAndroid Build Coastguard Worker         events_(events),
1542*635a8641SAndroid Build Coastguard Worker         received_msg_(false),
1543*635a8641SAndroid Build Coastguard Worker         received_noarg_reply_(false),
1544*635a8641SAndroid Build Coastguard Worker         done_issued_(false) {}
1545*635a8641SAndroid Build Coastguard Worker 
Run()1546*635a8641SAndroid Build Coastguard Worker   void Run() override {
1547*635a8641SAndroid Build Coastguard Worker     server_ready_event_->Wait();
1548*635a8641SAndroid Build Coastguard Worker     server_->ListenerThread()->task_runner()->PostTask(
1549*635a8641SAndroid Build Coastguard Worker         FROM_HERE, base::Bind(&RestrictedDispatchDeadlockServer::OnDoServerTask,
1550*635a8641SAndroid Build Coastguard Worker                               base::Unretained(server_)));
1551*635a8641SAndroid Build Coastguard Worker     peer_->ListenerThread()->task_runner()->PostTask(
1552*635a8641SAndroid Build Coastguard Worker         FROM_HERE,
1553*635a8641SAndroid Build Coastguard Worker         base::Bind(&RestrictedDispatchDeadlockClient2::OnDoClient2Task,
1554*635a8641SAndroid Build Coastguard Worker                    base::Unretained(peer_)));
1555*635a8641SAndroid Build Coastguard Worker     events_[0]->Wait();
1556*635a8641SAndroid Build Coastguard Worker     events_[1]->Wait();
1557*635a8641SAndroid Build Coastguard Worker     DCHECK(received_msg_ == false);
1558*635a8641SAndroid Build Coastguard Worker 
1559*635a8641SAndroid Build Coastguard Worker     Message* message = new SyncChannelTestMsg_NoArgs;
1560*635a8641SAndroid Build Coastguard Worker     message->set_unblock(true);
1561*635a8641SAndroid Build Coastguard Worker     Send(message);
1562*635a8641SAndroid Build Coastguard Worker     received_noarg_reply_ = true;
1563*635a8641SAndroid Build Coastguard Worker     PossiblyDone();
1564*635a8641SAndroid Build Coastguard Worker   }
1565*635a8641SAndroid Build Coastguard Worker 
1566*635a8641SAndroid Build Coastguard Worker  private:
OnMessageReceived(const Message & message)1567*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const Message& message) override {
1568*635a8641SAndroid Build Coastguard Worker     IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchDeadlockClient1, message)
1569*635a8641SAndroid Build Coastguard Worker      IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs)
1570*635a8641SAndroid Build Coastguard Worker     IPC_END_MESSAGE_MAP()
1571*635a8641SAndroid Build Coastguard Worker     return true;
1572*635a8641SAndroid Build Coastguard Worker   }
1573*635a8641SAndroid Build Coastguard Worker 
OnNoArgs()1574*635a8641SAndroid Build Coastguard Worker   void OnNoArgs() {
1575*635a8641SAndroid Build Coastguard Worker     received_msg_ = true;
1576*635a8641SAndroid Build Coastguard Worker     PossiblyDone();
1577*635a8641SAndroid Build Coastguard Worker   }
1578*635a8641SAndroid Build Coastguard Worker 
PossiblyDone()1579*635a8641SAndroid Build Coastguard Worker   void PossiblyDone() {
1580*635a8641SAndroid Build Coastguard Worker     if (received_noarg_reply_ && received_msg_) {
1581*635a8641SAndroid Build Coastguard Worker       DCHECK(done_issued_ == false);
1582*635a8641SAndroid Build Coastguard Worker       done_issued_ = true;
1583*635a8641SAndroid Build Coastguard Worker       Send(new SyncChannelTestMsg_Done);
1584*635a8641SAndroid Build Coastguard Worker       Done();
1585*635a8641SAndroid Build Coastguard Worker     }
1586*635a8641SAndroid Build Coastguard Worker   }
1587*635a8641SAndroid Build Coastguard Worker 
1588*635a8641SAndroid Build Coastguard Worker   RestrictedDispatchDeadlockServer* server_;
1589*635a8641SAndroid Build Coastguard Worker   RestrictedDispatchDeadlockClient2* peer_;
1590*635a8641SAndroid Build Coastguard Worker   WaitableEvent* server_ready_event_;
1591*635a8641SAndroid Build Coastguard Worker   WaitableEvent** events_;
1592*635a8641SAndroid Build Coastguard Worker   bool received_msg_;
1593*635a8641SAndroid Build Coastguard Worker   bool received_noarg_reply_;
1594*635a8641SAndroid Build Coastguard Worker   bool done_issued_;
1595*635a8641SAndroid Build Coastguard Worker };
1596*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCSyncChannelTest,RestrictedDispatchDeadlock)1597*635a8641SAndroid Build Coastguard Worker TEST_F(IPCSyncChannelTest, RestrictedDispatchDeadlock) {
1598*635a8641SAndroid Build Coastguard Worker   std::vector<Worker*> workers;
1599*635a8641SAndroid Build Coastguard Worker 
1600*635a8641SAndroid Build Coastguard Worker   // A shared worker thread so that server1 and server2 run on one thread.
1601*635a8641SAndroid Build Coastguard Worker   base::Thread worker_thread("RestrictedDispatchDeadlock");
1602*635a8641SAndroid Build Coastguard Worker   ASSERT_TRUE(worker_thread.Start());
1603*635a8641SAndroid Build Coastguard Worker 
1604*635a8641SAndroid Build Coastguard Worker   WaitableEvent server1_ready(base::WaitableEvent::ResetPolicy::AUTOMATIC,
1605*635a8641SAndroid Build Coastguard Worker                               base::WaitableEvent::InitialState::NOT_SIGNALED);
1606*635a8641SAndroid Build Coastguard Worker   WaitableEvent server2_ready(base::WaitableEvent::ResetPolicy::AUTOMATIC,
1607*635a8641SAndroid Build Coastguard Worker                               base::WaitableEvent::InitialState::NOT_SIGNALED);
1608*635a8641SAndroid Build Coastguard Worker 
1609*635a8641SAndroid Build Coastguard Worker   WaitableEvent event0(base::WaitableEvent::ResetPolicy::AUTOMATIC,
1610*635a8641SAndroid Build Coastguard Worker                        base::WaitableEvent::InitialState::NOT_SIGNALED);
1611*635a8641SAndroid Build Coastguard Worker   WaitableEvent event1(base::WaitableEvent::ResetPolicy::AUTOMATIC,
1612*635a8641SAndroid Build Coastguard Worker                        base::WaitableEvent::InitialState::NOT_SIGNALED);
1613*635a8641SAndroid Build Coastguard Worker   WaitableEvent event2(base::WaitableEvent::ResetPolicy::AUTOMATIC,
1614*635a8641SAndroid Build Coastguard Worker                        base::WaitableEvent::InitialState::NOT_SIGNALED);
1615*635a8641SAndroid Build Coastguard Worker   WaitableEvent event3(base::WaitableEvent::ResetPolicy::AUTOMATIC,
1616*635a8641SAndroid Build Coastguard Worker                        base::WaitableEvent::InitialState::NOT_SIGNALED);
1617*635a8641SAndroid Build Coastguard Worker   WaitableEvent* events[4] = {&event0, &event1, &event2, &event3};
1618*635a8641SAndroid Build Coastguard Worker 
1619*635a8641SAndroid Build Coastguard Worker   RestrictedDispatchDeadlockServer* server1;
1620*635a8641SAndroid Build Coastguard Worker   RestrictedDispatchDeadlockServer* server2;
1621*635a8641SAndroid Build Coastguard Worker   RestrictedDispatchDeadlockClient1* client1;
1622*635a8641SAndroid Build Coastguard Worker   RestrictedDispatchDeadlockClient2* client2;
1623*635a8641SAndroid Build Coastguard Worker 
1624*635a8641SAndroid Build Coastguard Worker   mojo::MessagePipe pipe1, pipe2;
1625*635a8641SAndroid Build Coastguard Worker   server2 = new RestrictedDispatchDeadlockServer(
1626*635a8641SAndroid Build Coastguard Worker       2, &server2_ready, events, NULL, std::move(pipe2.handle0));
1627*635a8641SAndroid Build Coastguard Worker   server2->OverrideThread(&worker_thread);
1628*635a8641SAndroid Build Coastguard Worker   workers.push_back(server2);
1629*635a8641SAndroid Build Coastguard Worker 
1630*635a8641SAndroid Build Coastguard Worker   client2 = new RestrictedDispatchDeadlockClient2(
1631*635a8641SAndroid Build Coastguard Worker       server2, &server2_ready, events, std::move(pipe2.handle1));
1632*635a8641SAndroid Build Coastguard Worker   workers.push_back(client2);
1633*635a8641SAndroid Build Coastguard Worker 
1634*635a8641SAndroid Build Coastguard Worker   server1 = new RestrictedDispatchDeadlockServer(
1635*635a8641SAndroid Build Coastguard Worker       1, &server1_ready, events, server2, std::move(pipe1.handle0));
1636*635a8641SAndroid Build Coastguard Worker   server1->OverrideThread(&worker_thread);
1637*635a8641SAndroid Build Coastguard Worker   workers.push_back(server1);
1638*635a8641SAndroid Build Coastguard Worker 
1639*635a8641SAndroid Build Coastguard Worker   client1 = new RestrictedDispatchDeadlockClient1(
1640*635a8641SAndroid Build Coastguard Worker       server1, client2, &server1_ready, events, std::move(pipe1.handle1));
1641*635a8641SAndroid Build Coastguard Worker   workers.push_back(client1);
1642*635a8641SAndroid Build Coastguard Worker 
1643*635a8641SAndroid Build Coastguard Worker   RunTest(workers);
1644*635a8641SAndroid Build Coastguard Worker }
1645*635a8641SAndroid Build Coastguard Worker 
1646*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
1647*635a8641SAndroid Build Coastguard Worker 
1648*635a8641SAndroid Build Coastguard Worker // This test case inspired by crbug.com/120530
1649*635a8641SAndroid Build Coastguard Worker // We create 4 workers that pipe to each other W1->W2->W3->W4->W1 then we send a
1650*635a8641SAndroid Build Coastguard Worker // message that recurses through 3, 4 or 5 steps to make sure, say, W1 can
1651*635a8641SAndroid Build Coastguard Worker // re-enter when called from W4 while it's sending a message to W2.
1652*635a8641SAndroid Build Coastguard Worker // The first worker drives the whole test so it must be treated specially.
1653*635a8641SAndroid Build Coastguard Worker 
1654*635a8641SAndroid Build Coastguard Worker class RestrictedDispatchPipeWorker : public Worker {
1655*635a8641SAndroid Build Coastguard Worker  public:
RestrictedDispatchPipeWorker(mojo::ScopedMessagePipeHandle channel_handle1,WaitableEvent * event1,mojo::ScopedMessagePipeHandle channel_handle2,WaitableEvent * event2,int group,int * success)1656*635a8641SAndroid Build Coastguard Worker   RestrictedDispatchPipeWorker(mojo::ScopedMessagePipeHandle channel_handle1,
1657*635a8641SAndroid Build Coastguard Worker                                WaitableEvent* event1,
1658*635a8641SAndroid Build Coastguard Worker                                mojo::ScopedMessagePipeHandle channel_handle2,
1659*635a8641SAndroid Build Coastguard Worker                                WaitableEvent* event2,
1660*635a8641SAndroid Build Coastguard Worker                                int group,
1661*635a8641SAndroid Build Coastguard Worker                                int* success)
1662*635a8641SAndroid Build Coastguard Worker       : Worker(std::move(channel_handle1), Channel::MODE_SERVER),
1663*635a8641SAndroid Build Coastguard Worker         event1_(event1),
1664*635a8641SAndroid Build Coastguard Worker         event2_(event2),
1665*635a8641SAndroid Build Coastguard Worker         other_channel_handle_(std::move(channel_handle2)),
1666*635a8641SAndroid Build Coastguard Worker         group_(group),
1667*635a8641SAndroid Build Coastguard Worker         success_(success) {}
1668*635a8641SAndroid Build Coastguard Worker 
OnPingTTL(int ping,int * ret)1669*635a8641SAndroid Build Coastguard Worker   void OnPingTTL(int ping, int* ret) {
1670*635a8641SAndroid Build Coastguard Worker     *ret = 0;
1671*635a8641SAndroid Build Coastguard Worker     if (!ping)
1672*635a8641SAndroid Build Coastguard Worker       return;
1673*635a8641SAndroid Build Coastguard Worker     other_channel_->Send(new SyncChannelTestMsg_PingTTL(ping - 1, ret));
1674*635a8641SAndroid Build Coastguard Worker     ++*ret;
1675*635a8641SAndroid Build Coastguard Worker   }
1676*635a8641SAndroid Build Coastguard Worker 
OnDone()1677*635a8641SAndroid Build Coastguard Worker   void OnDone() {
1678*635a8641SAndroid Build Coastguard Worker     if (is_first())
1679*635a8641SAndroid Build Coastguard Worker       return;
1680*635a8641SAndroid Build Coastguard Worker     other_channel_->Send(new SyncChannelTestMsg_Done);
1681*635a8641SAndroid Build Coastguard Worker     other_channel_.reset();
1682*635a8641SAndroid Build Coastguard Worker     Done();
1683*635a8641SAndroid Build Coastguard Worker   }
1684*635a8641SAndroid Build Coastguard Worker 
Run()1685*635a8641SAndroid Build Coastguard Worker   void Run() override {
1686*635a8641SAndroid Build Coastguard Worker     channel()->SetRestrictDispatchChannelGroup(group_);
1687*635a8641SAndroid Build Coastguard Worker     if (is_first())
1688*635a8641SAndroid Build Coastguard Worker       event1_->Signal();
1689*635a8641SAndroid Build Coastguard Worker     event2_->Wait();
1690*635a8641SAndroid Build Coastguard Worker     other_channel_ = SyncChannel::Create(
1691*635a8641SAndroid Build Coastguard Worker         other_channel_handle_.release(), IPC::Channel::MODE_CLIENT, this,
1692*635a8641SAndroid Build Coastguard Worker         ipc_thread().task_runner(), base::ThreadTaskRunnerHandle::Get(), true,
1693*635a8641SAndroid Build Coastguard Worker         shutdown_event());
1694*635a8641SAndroid Build Coastguard Worker     other_channel_->SetRestrictDispatchChannelGroup(group_);
1695*635a8641SAndroid Build Coastguard Worker     if (!is_first()) {
1696*635a8641SAndroid Build Coastguard Worker       event1_->Signal();
1697*635a8641SAndroid Build Coastguard Worker       return;
1698*635a8641SAndroid Build Coastguard Worker     }
1699*635a8641SAndroid Build Coastguard Worker     *success_ = 0;
1700*635a8641SAndroid Build Coastguard Worker     int value = 0;
1701*635a8641SAndroid Build Coastguard Worker     OnPingTTL(3, &value);
1702*635a8641SAndroid Build Coastguard Worker     *success_ += (value == 3);
1703*635a8641SAndroid Build Coastguard Worker     OnPingTTL(4, &value);
1704*635a8641SAndroid Build Coastguard Worker     *success_ += (value == 4);
1705*635a8641SAndroid Build Coastguard Worker     OnPingTTL(5, &value);
1706*635a8641SAndroid Build Coastguard Worker     *success_ += (value == 5);
1707*635a8641SAndroid Build Coastguard Worker     other_channel_->Send(new SyncChannelTestMsg_Done);
1708*635a8641SAndroid Build Coastguard Worker     other_channel_.reset();
1709*635a8641SAndroid Build Coastguard Worker     Done();
1710*635a8641SAndroid Build Coastguard Worker   }
1711*635a8641SAndroid Build Coastguard Worker 
is_first()1712*635a8641SAndroid Build Coastguard Worker   bool is_first() { return !!success_; }
1713*635a8641SAndroid Build Coastguard Worker 
1714*635a8641SAndroid Build Coastguard Worker  private:
OnMessageReceived(const Message & message)1715*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const Message& message) override {
1716*635a8641SAndroid Build Coastguard Worker     IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchPipeWorker, message)
1717*635a8641SAndroid Build Coastguard Worker      IPC_MESSAGE_HANDLER(SyncChannelTestMsg_PingTTL, OnPingTTL)
1718*635a8641SAndroid Build Coastguard Worker      IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, OnDone)
1719*635a8641SAndroid Build Coastguard Worker     IPC_END_MESSAGE_MAP()
1720*635a8641SAndroid Build Coastguard Worker     return true;
1721*635a8641SAndroid Build Coastguard Worker   }
1722*635a8641SAndroid Build Coastguard Worker 
1723*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<SyncChannel> other_channel_;
1724*635a8641SAndroid Build Coastguard Worker   WaitableEvent* event1_;
1725*635a8641SAndroid Build Coastguard Worker   WaitableEvent* event2_;
1726*635a8641SAndroid Build Coastguard Worker   mojo::ScopedMessagePipeHandle other_channel_handle_;
1727*635a8641SAndroid Build Coastguard Worker   int group_;
1728*635a8641SAndroid Build Coastguard Worker   int* success_;
1729*635a8641SAndroid Build Coastguard Worker };
1730*635a8641SAndroid Build Coastguard Worker 
1731*635a8641SAndroid Build Coastguard Worker #if defined(OS_ANDROID)
1732*635a8641SAndroid Build Coastguard Worker #define MAYBE_RestrictedDispatch4WayDeadlock \
1733*635a8641SAndroid Build Coastguard Worker   DISABLED_RestrictedDispatch4WayDeadlock
1734*635a8641SAndroid Build Coastguard Worker #else
1735*635a8641SAndroid Build Coastguard Worker #define MAYBE_RestrictedDispatch4WayDeadlock RestrictedDispatch4WayDeadlock
1736*635a8641SAndroid Build Coastguard Worker #endif
TEST_F(IPCSyncChannelTest,MAYBE_RestrictedDispatch4WayDeadlock)1737*635a8641SAndroid Build Coastguard Worker TEST_F(IPCSyncChannelTest, MAYBE_RestrictedDispatch4WayDeadlock) {
1738*635a8641SAndroid Build Coastguard Worker   int success = 0;
1739*635a8641SAndroid Build Coastguard Worker   std::vector<Worker*> workers;
1740*635a8641SAndroid Build Coastguard Worker   WaitableEvent event0(base::WaitableEvent::ResetPolicy::MANUAL,
1741*635a8641SAndroid Build Coastguard Worker                        base::WaitableEvent::InitialState::NOT_SIGNALED);
1742*635a8641SAndroid Build Coastguard Worker   WaitableEvent event1(base::WaitableEvent::ResetPolicy::MANUAL,
1743*635a8641SAndroid Build Coastguard Worker                        base::WaitableEvent::InitialState::NOT_SIGNALED);
1744*635a8641SAndroid Build Coastguard Worker   WaitableEvent event2(base::WaitableEvent::ResetPolicy::MANUAL,
1745*635a8641SAndroid Build Coastguard Worker                        base::WaitableEvent::InitialState::NOT_SIGNALED);
1746*635a8641SAndroid Build Coastguard Worker   WaitableEvent event3(base::WaitableEvent::ResetPolicy::MANUAL,
1747*635a8641SAndroid Build Coastguard Worker                        base::WaitableEvent::InitialState::NOT_SIGNALED);
1748*635a8641SAndroid Build Coastguard Worker   mojo::MessagePipe pipe0, pipe1, pipe2, pipe3;
1749*635a8641SAndroid Build Coastguard Worker   workers.push_back(new RestrictedDispatchPipeWorker(
1750*635a8641SAndroid Build Coastguard Worker       std::move(pipe0.handle0), &event0, std::move(pipe1.handle1), &event1, 1,
1751*635a8641SAndroid Build Coastguard Worker       &success));
1752*635a8641SAndroid Build Coastguard Worker   workers.push_back(new RestrictedDispatchPipeWorker(
1753*635a8641SAndroid Build Coastguard Worker       std::move(pipe1.handle0), &event1, std::move(pipe2.handle1), &event2, 2,
1754*635a8641SAndroid Build Coastguard Worker       NULL));
1755*635a8641SAndroid Build Coastguard Worker   workers.push_back(new RestrictedDispatchPipeWorker(
1756*635a8641SAndroid Build Coastguard Worker       std::move(pipe2.handle0), &event2, std::move(pipe3.handle1), &event3, 3,
1757*635a8641SAndroid Build Coastguard Worker       NULL));
1758*635a8641SAndroid Build Coastguard Worker   workers.push_back(new RestrictedDispatchPipeWorker(
1759*635a8641SAndroid Build Coastguard Worker       std::move(pipe3.handle0), &event3, std::move(pipe0.handle1), &event0, 4,
1760*635a8641SAndroid Build Coastguard Worker       NULL));
1761*635a8641SAndroid Build Coastguard Worker   RunTest(workers);
1762*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(3, success);
1763*635a8641SAndroid Build Coastguard Worker }
1764*635a8641SAndroid Build Coastguard Worker 
1765*635a8641SAndroid Build Coastguard Worker //------------------------------------------------------------------------------
1766*635a8641SAndroid Build Coastguard Worker 
1767*635a8641SAndroid Build Coastguard Worker // This test case inspired by crbug.com/122443
1768*635a8641SAndroid Build Coastguard Worker // We want to make sure a reply message with the unblock flag set correctly
1769*635a8641SAndroid Build Coastguard Worker // behaves as a reply, not a regular message.
1770*635a8641SAndroid Build Coastguard Worker // We have 3 workers. Server1 will send a message to Server2 (which will block),
1771*635a8641SAndroid Build Coastguard Worker // during which it will dispatch a message comming from Client, at which point
1772*635a8641SAndroid Build Coastguard Worker // it will send another message to Server2. While sending that second message it
1773*635a8641SAndroid Build Coastguard Worker // will receive a reply from Server1 with the unblock flag.
1774*635a8641SAndroid Build Coastguard Worker 
1775*635a8641SAndroid Build Coastguard Worker class ReentrantReplyServer1 : public Worker {
1776*635a8641SAndroid Build Coastguard Worker  public:
ReentrantReplyServer1(WaitableEvent * server_ready,mojo::ScopedMessagePipeHandle channel_handle1,mojo::ScopedMessagePipeHandle channel_handle2)1777*635a8641SAndroid Build Coastguard Worker   ReentrantReplyServer1(WaitableEvent* server_ready,
1778*635a8641SAndroid Build Coastguard Worker                         mojo::ScopedMessagePipeHandle channel_handle1,
1779*635a8641SAndroid Build Coastguard Worker                         mojo::ScopedMessagePipeHandle channel_handle2)
1780*635a8641SAndroid Build Coastguard Worker       : Worker(std::move(channel_handle1), Channel::MODE_SERVER),
1781*635a8641SAndroid Build Coastguard Worker         server_ready_(server_ready),
1782*635a8641SAndroid Build Coastguard Worker         other_channel_handle_(std::move(channel_handle2)) {}
1783*635a8641SAndroid Build Coastguard Worker 
Run()1784*635a8641SAndroid Build Coastguard Worker   void Run() override {
1785*635a8641SAndroid Build Coastguard Worker     server2_channel_ = SyncChannel::Create(
1786*635a8641SAndroid Build Coastguard Worker         other_channel_handle_.release(), IPC::Channel::MODE_CLIENT, this,
1787*635a8641SAndroid Build Coastguard Worker         ipc_thread().task_runner(), base::ThreadTaskRunnerHandle::Get(), true,
1788*635a8641SAndroid Build Coastguard Worker         shutdown_event());
1789*635a8641SAndroid Build Coastguard Worker     server_ready_->Signal();
1790*635a8641SAndroid Build Coastguard Worker     Message* msg = new SyncChannelTestMsg_Reentrant1();
1791*635a8641SAndroid Build Coastguard Worker     server2_channel_->Send(msg);
1792*635a8641SAndroid Build Coastguard Worker     server2_channel_.reset();
1793*635a8641SAndroid Build Coastguard Worker     Done();
1794*635a8641SAndroid Build Coastguard Worker   }
1795*635a8641SAndroid Build Coastguard Worker 
1796*635a8641SAndroid Build Coastguard Worker  private:
OnMessageReceived(const Message & message)1797*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const Message& message) override {
1798*635a8641SAndroid Build Coastguard Worker     IPC_BEGIN_MESSAGE_MAP(ReentrantReplyServer1, message)
1799*635a8641SAndroid Build Coastguard Worker      IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Reentrant2, OnReentrant2)
1800*635a8641SAndroid Build Coastguard Worker      IPC_REPLY_HANDLER(OnReply)
1801*635a8641SAndroid Build Coastguard Worker     IPC_END_MESSAGE_MAP()
1802*635a8641SAndroid Build Coastguard Worker     return true;
1803*635a8641SAndroid Build Coastguard Worker   }
1804*635a8641SAndroid Build Coastguard Worker 
OnReentrant2()1805*635a8641SAndroid Build Coastguard Worker   void OnReentrant2() {
1806*635a8641SAndroid Build Coastguard Worker     Message* msg = new SyncChannelTestMsg_Reentrant3();
1807*635a8641SAndroid Build Coastguard Worker     server2_channel_->Send(msg);
1808*635a8641SAndroid Build Coastguard Worker   }
1809*635a8641SAndroid Build Coastguard Worker 
OnReply(const Message & message)1810*635a8641SAndroid Build Coastguard Worker   void OnReply(const Message& message) {
1811*635a8641SAndroid Build Coastguard Worker     // If we get here, the Send() will never receive the reply (thus would
1812*635a8641SAndroid Build Coastguard Worker     // hang), so abort instead.
1813*635a8641SAndroid Build Coastguard Worker     LOG(FATAL) << "Reply message was dispatched";
1814*635a8641SAndroid Build Coastguard Worker   }
1815*635a8641SAndroid Build Coastguard Worker 
1816*635a8641SAndroid Build Coastguard Worker   WaitableEvent* server_ready_;
1817*635a8641SAndroid Build Coastguard Worker   std::unique_ptr<SyncChannel> server2_channel_;
1818*635a8641SAndroid Build Coastguard Worker   mojo::ScopedMessagePipeHandle other_channel_handle_;
1819*635a8641SAndroid Build Coastguard Worker };
1820*635a8641SAndroid Build Coastguard Worker 
1821*635a8641SAndroid Build Coastguard Worker class ReentrantReplyServer2 : public Worker {
1822*635a8641SAndroid Build Coastguard Worker  public:
ReentrantReplyServer2(mojo::ScopedMessagePipeHandle channel_handle)1823*635a8641SAndroid Build Coastguard Worker   ReentrantReplyServer2(mojo::ScopedMessagePipeHandle channel_handle)
1824*635a8641SAndroid Build Coastguard Worker       : Worker(std::move(channel_handle), Channel::MODE_SERVER), reply_(NULL) {}
1825*635a8641SAndroid Build Coastguard Worker 
1826*635a8641SAndroid Build Coastguard Worker  private:
OnMessageReceived(const Message & message)1827*635a8641SAndroid Build Coastguard Worker   bool OnMessageReceived(const Message& message) override {
1828*635a8641SAndroid Build Coastguard Worker     IPC_BEGIN_MESSAGE_MAP(ReentrantReplyServer2, message)
1829*635a8641SAndroid Build Coastguard Worker      IPC_MESSAGE_HANDLER_DELAY_REPLY(
1830*635a8641SAndroid Build Coastguard Worker          SyncChannelTestMsg_Reentrant1, OnReentrant1)
1831*635a8641SAndroid Build Coastguard Worker      IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Reentrant3, OnReentrant3)
1832*635a8641SAndroid Build Coastguard Worker     IPC_END_MESSAGE_MAP()
1833*635a8641SAndroid Build Coastguard Worker     return true;
1834*635a8641SAndroid Build Coastguard Worker   }
1835*635a8641SAndroid Build Coastguard Worker 
OnReentrant1(Message * reply)1836*635a8641SAndroid Build Coastguard Worker   void OnReentrant1(Message* reply) {
1837*635a8641SAndroid Build Coastguard Worker     DCHECK(!reply_);
1838*635a8641SAndroid Build Coastguard Worker     reply_ = reply;
1839*635a8641SAndroid Build Coastguard Worker   }
1840*635a8641SAndroid Build Coastguard Worker 
OnReentrant3()1841*635a8641SAndroid Build Coastguard Worker   void OnReentrant3() {
1842*635a8641SAndroid Build Coastguard Worker     DCHECK(reply_);
1843*635a8641SAndroid Build Coastguard Worker     Message* reply = reply_;
1844*635a8641SAndroid Build Coastguard Worker     reply_ = NULL;
1845*635a8641SAndroid Build Coastguard Worker     reply->set_unblock(true);
1846*635a8641SAndroid Build Coastguard Worker     Send(reply);
1847*635a8641SAndroid Build Coastguard Worker     Done();
1848*635a8641SAndroid Build Coastguard Worker   }
1849*635a8641SAndroid Build Coastguard Worker 
1850*635a8641SAndroid Build Coastguard Worker   Message* reply_;
1851*635a8641SAndroid Build Coastguard Worker };
1852*635a8641SAndroid Build Coastguard Worker 
1853*635a8641SAndroid Build Coastguard Worker class ReentrantReplyClient : public Worker {
1854*635a8641SAndroid Build Coastguard Worker  public:
ReentrantReplyClient(WaitableEvent * server_ready,mojo::ScopedMessagePipeHandle channel_handle)1855*635a8641SAndroid Build Coastguard Worker   ReentrantReplyClient(WaitableEvent* server_ready,
1856*635a8641SAndroid Build Coastguard Worker                        mojo::ScopedMessagePipeHandle channel_handle)
1857*635a8641SAndroid Build Coastguard Worker       : Worker(std::move(channel_handle), Channel::MODE_CLIENT),
1858*635a8641SAndroid Build Coastguard Worker         server_ready_(server_ready) {}
1859*635a8641SAndroid Build Coastguard Worker 
Run()1860*635a8641SAndroid Build Coastguard Worker   void Run() override {
1861*635a8641SAndroid Build Coastguard Worker     server_ready_->Wait();
1862*635a8641SAndroid Build Coastguard Worker     Send(new SyncChannelTestMsg_Reentrant2());
1863*635a8641SAndroid Build Coastguard Worker     Done();
1864*635a8641SAndroid Build Coastguard Worker   }
1865*635a8641SAndroid Build Coastguard Worker 
1866*635a8641SAndroid Build Coastguard Worker  private:
1867*635a8641SAndroid Build Coastguard Worker   WaitableEvent* server_ready_;
1868*635a8641SAndroid Build Coastguard Worker };
1869*635a8641SAndroid Build Coastguard Worker 
TEST_F(IPCSyncChannelTest,ReentrantReply)1870*635a8641SAndroid Build Coastguard Worker TEST_F(IPCSyncChannelTest, ReentrantReply) {
1871*635a8641SAndroid Build Coastguard Worker   std::vector<Worker*> workers;
1872*635a8641SAndroid Build Coastguard Worker   WaitableEvent server_ready(base::WaitableEvent::ResetPolicy::AUTOMATIC,
1873*635a8641SAndroid Build Coastguard Worker                              base::WaitableEvent::InitialState::NOT_SIGNALED);
1874*635a8641SAndroid Build Coastguard Worker   mojo::MessagePipe pipe1, pipe2;
1875*635a8641SAndroid Build Coastguard Worker   workers.push_back(new ReentrantReplyServer2(std::move(pipe2.handle0)));
1876*635a8641SAndroid Build Coastguard Worker   workers.push_back(new ReentrantReplyServer1(
1877*635a8641SAndroid Build Coastguard Worker       &server_ready, std::move(pipe1.handle0), std::move(pipe2.handle1)));
1878*635a8641SAndroid Build Coastguard Worker   workers.push_back(
1879*635a8641SAndroid Build Coastguard Worker       new ReentrantReplyClient(&server_ready, std::move(pipe1.handle1)));
1880*635a8641SAndroid Build Coastguard Worker   RunTest(workers);
1881*635a8641SAndroid Build Coastguard Worker }
1882*635a8641SAndroid Build Coastguard Worker 
1883*635a8641SAndroid Build Coastguard Worker }  // namespace
1884*635a8641SAndroid Build Coastguard Worker }  // namespace IPC
1885