blob: e3a71927a9b896081b16f7511c295bfc324d9c21 [file] [log] [blame]
[email protected]522cc10d2012-01-11 22:39:541// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]22b42c52010-12-20 06:59:235#include "ipc/ipc_sync_channel.h"
6
avi246998d82015-12-22 02:39:047#include <stddef.h>
8
initial.commit09911bf2008-07-26 23:55:299#include <string>
10#include <vector>
11
[email protected]72b6f8e22011-11-12 21:16:4112#include "base/bind.h"
skyostile687bdff2015-05-12 11:29:2113#include "base/location.h"
initial.commit09911bf2008-07-26 23:55:2914#include "base/logging.h"
tfarina4da82752015-09-16 09:56:2115#include "base/macros.h"
[email protected]3b63f8f42011-03-28 01:54:1516#include "base/memory/scoped_ptr.h"
[email protected]e66ef602013-07-24 05:15:2417#include "base/process/process_handle.h"
[email protected]2d6e6a72013-02-08 20:11:0218#include "base/run_loop.h"
skyostile687bdff2015-05-12 11:29:2119#include "base/single_thread_task_runner.h"
[email protected]4aa794a12013-06-11 06:32:1820#include "base/strings/string_util.h"
21#include "base/synchronization/waitable_event.h"
skyostile687bdff2015-05-12 11:29:2122#include "base/thread_task_runner_handle.h"
[email protected]f214f8792011-01-01 02:17:0823#include "base/threading/platform_thread.h"
[email protected]34b99632011-01-01 01:01:0624#include "base/threading/thread.h"
avi246998d82015-12-22 02:39:0425#include "build/build_config.h"
[email protected]57319ce2012-06-11 22:35:2626#include "ipc/ipc_listener.h"
[email protected]946d1b22009-07-22 23:57:2127#include "ipc/ipc_message.h"
[email protected]57319ce2012-06-11 22:35:2628#include "ipc/ipc_sender.h"
[email protected]1e9499c2010-04-06 20:33:3629#include "ipc/ipc_sync_message_filter.h"
[email protected]21fa3a12010-12-08 23:34:1630#include "ipc/ipc_sync_message_unittest.h"
initial.commit09911bf2008-07-26 23:55:2931#include "testing/gtest/include/gtest/gtest.h"
32
[email protected]aa96ae772009-01-20 22:08:1533using base::WaitableEvent;
[email protected]c9e0c7332011-05-13 22:42:4134
[email protected]2d6e6a72013-02-08 20:11:0235namespace IPC {
[email protected]dd3eac22008-08-26 07:28:3436namespace {
37
initial.commit09911bf2008-07-26 23:55:2938// Base class for a "process" with listener and IPC threads.
[email protected]57319ce2012-06-11 22:35:2639class Worker : public Listener, public Sender {
initial.commit09911bf2008-07-26 23:55:2940 public:
41 // Will create a channel without a name.
erikchen99fbfc662016-04-08 22:37:4842 Worker(Channel::Mode mode,
43 const std::string& thread_name,
44 const std::string& channel_name)
[email protected]aa96ae772009-01-20 22:08:1545 : done_(new WaitableEvent(false, false)),
46 channel_created_(new WaitableEvent(false, false)),
erikchen99fbfc662016-04-08 22:37:4847 channel_name_(channel_name),
initial.commit09911bf2008-07-26 23:55:2948 mode_(mode),
49 ipc_thread_((thread_name + "_ipc").c_str()),
50 listener_thread_((thread_name + "_listener").c_str()),
[email protected]8930d472009-02-21 08:05:2851 overrided_thread_(NULL),
[email protected]bf2a9092013-01-08 06:09:0752 shutdown_event_(true, false),
erikchen99fbfc662016-04-08 22:37:4853 is_shutdown_(false) {}
initial.commit09911bf2008-07-26 23:55:2954
55 // Will create a named channel and use this name for the threads' name.
[email protected]9a3a293b2009-06-04 22:28:1656 Worker(const std::string& channel_name, Channel::Mode mode)
[email protected]aa96ae772009-01-20 22:08:1557 : done_(new WaitableEvent(false, false)),
58 channel_created_(new WaitableEvent(false, false)),
59 channel_name_(channel_name),
initial.commit09911bf2008-07-26 23:55:2960 mode_(mode),
[email protected]9a3a293b2009-06-04 22:28:1661 ipc_thread_((channel_name + "_ipc").c_str()),
62 listener_thread_((channel_name + "_listener").c_str()),
[email protected]8930d472009-02-21 08:05:2863 overrided_thread_(NULL),
[email protected]bf2a9092013-01-08 06:09:0764 shutdown_event_(true, false),
65 is_shutdown_(false) {
[email protected]8a734422009-10-27 11:28:5866 }
initial.commit09911bf2008-07-26 23:55:2967
dchengfe61fca2014-10-22 02:29:5268 ~Worker() override {
[email protected]bf2a9092013-01-08 06:09:0769 // Shutdown() must be called before destruction.
70 CHECK(is_shutdown_);
initial.commit09911bf2008-07-26 23:55:2971 }
72 void AddRef() { }
73 void Release() { }
dchengfe61fca2014-10-22 02:29:5274 bool Send(Message* msg) override { return channel_->Send(msg); }
[email protected]aa96ae772009-01-20 22:08:1575 void WaitForChannelCreation() { channel_created_->Wait(); }
[email protected]3cdb7af812008-10-24 19:21:1376 void CloseChannel() {
[email protected]fd0a773a2013-04-30 20:55:0377 DCHECK(base::MessageLoop::current() == ListenerThread()->message_loop());
[email protected]3cdb7af812008-10-24 19:21:1378 channel_->Close();
79 }
initial.commit09911bf2008-07-26 23:55:2980 void Start() {
[email protected]fd0a773a2013-04-30 20:55:0381 StartThread(&listener_thread_, base::MessageLoop::TYPE_DEFAULT);
skyostile687bdff2015-05-12 11:29:2182 ListenerThread()->task_runner()->PostTask(
[email protected]72b6f8e22011-11-12 21:16:4183 FROM_HERE, base::Bind(&Worker::OnStart, this));
initial.commit09911bf2008-07-26 23:55:2984 }
[email protected]bf2a9092013-01-08 06:09:0785 void Shutdown() {
86 // The IPC thread needs to outlive SyncChannel. We can't do this in
87 // ~Worker(), since that'll reset the vtable pointer (to Worker's), which
88 // may result in a race conditions. See http://crbug.com/25841.
89 WaitableEvent listener_done(false, false), ipc_done(false, false);
skyostile687bdff2015-05-12 11:29:2190 ListenerThread()->task_runner()->PostTask(
[email protected]bf2a9092013-01-08 06:09:0791 FROM_HERE, base::Bind(&Worker::OnListenerThreadShutdown1, this,
92 &listener_done, &ipc_done));
93 listener_done.Wait();
94 ipc_done.Wait();
95 ipc_thread_.Stop();
96 listener_thread_.Stop();
97 is_shutdown_ = true;
98 }
[email protected]ab820df2008-08-26 05:55:1099 void OverrideThread(base::Thread* overrided_thread) {
initial.commit09911bf2008-07-26 23:55:29100 DCHECK(overrided_thread_ == NULL);
101 overrided_thread_ = overrided_thread;
102 }
[email protected]5855f1d2014-04-16 16:50:43103 bool SendAnswerToLife(bool pump, bool succeed) {
[email protected]4df10d612008-11-12 00:38:26104 int answer = 0;
105 SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer);
106 if (pump)
107 msg->EnableMessagePumping();
[email protected]5855f1d2014-04-16 16:50:43108 bool result = Send(msg);
[email protected]9eec2252009-12-01 02:34:18109 DCHECK_EQ(result, succeed);
110 DCHECK_EQ(answer, (succeed ? 42 : 0));
[email protected]4df10d612008-11-12 00:38:26111 return result;
112 }
113 bool SendDouble(bool pump, bool succeed) {
114 int answer = 0;
115 SyncMessage* msg = new SyncChannelTestMsg_Double(5, &answer);
116 if (pump)
117 msg->EnableMessagePumping();
118 bool result = Send(msg);
[email protected]9eec2252009-12-01 02:34:18119 DCHECK_EQ(result, succeed);
120 DCHECK_EQ(answer, (succeed ? 10 : 0));
[email protected]4df10d612008-11-12 00:38:26121 return result;
122 }
[email protected]952394af2011-11-16 01:06:46123 const std::string& channel_name() { return channel_name_; }
initial.commit09911bf2008-07-26 23:55:29124 Channel::Mode mode() { return mode_; }
[email protected]aa96ae772009-01-20 22:08:15125 WaitableEvent* done_event() { return done_.get(); }
[email protected]1e9499c2010-04-06 20:33:36126 WaitableEvent* shutdown_event() { return &shutdown_event_; }
[email protected]9eec2252009-12-01 02:34:18127 void ResetChannel() { channel_.reset(); }
initial.commit09911bf2008-07-26 23:55:29128 // Derived classes need to call this when they've completed their part of
129 // the test.
[email protected]aa96ae772009-01-20 22:08:15130 void Done() { done_->Signal(); }
[email protected]1e9499c2010-04-06 20:33:36131
132 protected:
[email protected]c9e0c7332011-05-13 22:42:41133 SyncChannel* channel() { return channel_.get(); }
thakisb25789fb2015-04-23 05:40:02134 // Functions for derived classes to implement if they wish.
initial.commit09911bf2008-07-26 23:55:29135 virtual void Run() { }
initial.commit09911bf2008-07-26 23:55:29136 virtual void OnAnswer(int* answer) { NOTREACHED(); }
137 virtual void OnAnswerDelay(Message* reply_msg) {
138 // The message handler map below can only take one entry for
139 // SyncChannelTestMsg_AnswerToLife, so since some classes want
140 // the normal version while other want the delayed reply, we
141 // call the normal version if the derived class didn't override
142 // this function.
143 int answer;
144 OnAnswer(&answer);
145 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, answer);
146 Send(reply_msg);
147 }
[email protected]3cdb7af812008-10-24 19:21:13148 virtual void OnDouble(int in, int* out) { NOTREACHED(); }
149 virtual void OnDoubleDelay(int in, Message* reply_msg) {
150 int result;
151 OnDouble(in, &result);
152 SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, result);
153 Send(reply_msg);
154 }
initial.commit09911bf2008-07-26 23:55:29155
[email protected]ac0efda2009-10-14 16:22:02156 virtual void OnNestedTestMsg(Message* reply_msg) {
157 NOTREACHED();
158 }
159
[email protected]952394af2011-11-16 01:06:46160 virtual SyncChannel* CreateChannel() {
[email protected]fca876a12014-06-05 16:15:38161 scoped_ptr<SyncChannel> channel = SyncChannel::Create(
skyostile687bdff2015-05-12 11:29:21162 channel_name_, mode_, this, ipc_thread_.task_runner().get(), true,
erikchen30dc2812015-09-24 03:26:38163 &shutdown_event_);
[email protected]fca876a12014-06-05 16:15:38164 return channel.release();
[email protected]952394af2011-11-16 01:06:46165 }
166
[email protected]3cdb7af812008-10-24 19:21:13167 base::Thread* ListenerThread() {
168 return overrided_thread_ ? overrided_thread_ : &listener_thread_;
169 }
[email protected]87339f02010-09-02 21:45:50170
[email protected]54af05f2011-04-08 03:38:21171 const base::Thread& ipc_thread() const { return ipc_thread_; }
172
[email protected]87339f02010-09-02 21:45:50173 private:
initial.commit09911bf2008-07-26 23:55:29174 // Called on the listener thread to create the sync channel.
175 void OnStart() {
initial.commit09911bf2008-07-26 23:55:29176 // Link ipc_thread_, listener_thread_ and channel_ altogether.
[email protected]fd0a773a2013-04-30 20:55:03177 StartThread(&ipc_thread_, base::MessageLoop::TYPE_IO);
[email protected]952394af2011-11-16 01:06:46178 channel_.reset(CreateChannel());
[email protected]aa96ae772009-01-20 22:08:15179 channel_created_->Signal();
initial.commit09911bf2008-07-26 23:55:29180 Run();
181 }
182
[email protected]9d4ff5ed2009-03-03 00:21:56183 void OnListenerThreadShutdown1(WaitableEvent* listener_event,
184 WaitableEvent* ipc_event) {
[email protected]3cdb7af812008-10-24 19:21:13185 // SyncChannel needs to be destructed on the thread that it was created on.
186 channel_.reset();
[email protected]9d4ff5ed2009-03-03 00:21:56187
[email protected]2d6e6a72013-02-08 20:11:02188 base::RunLoop().RunUntilIdle();
[email protected]aa96ae772009-01-20 22:08:15189
[email protected]72b6f8e22011-11-12 21:16:41190 ipc_thread_.message_loop()->PostTask(
191 FROM_HERE, base::Bind(&Worker::OnIPCThreadShutdown, this,
192 listener_event, ipc_event));
[email protected]3cdb7af812008-10-24 19:21:13193 }
194
[email protected]9d4ff5ed2009-03-03 00:21:56195 void OnIPCThreadShutdown(WaitableEvent* listener_event,
196 WaitableEvent* ipc_event) {
[email protected]2d6e6a72013-02-08 20:11:02197 base::RunLoop().RunUntilIdle();
[email protected]aa96ae772009-01-20 22:08:15198 ipc_event->Signal();
[email protected]9d4ff5ed2009-03-03 00:21:56199
skyostile687bdff2015-05-12 11:29:21200 listener_thread_.task_runner()->PostTask(
201 FROM_HERE,
202 base::Bind(&Worker::OnListenerThreadShutdown2, this, listener_event));
[email protected]9d4ff5ed2009-03-03 00:21:56203 }
204
205 void OnListenerThreadShutdown2(WaitableEvent* listener_event) {
[email protected]2d6e6a72013-02-08 20:11:02206 base::RunLoop().RunUntilIdle();
[email protected]9d4ff5ed2009-03-03 00:21:56207 listener_event->Signal();
[email protected]3cdb7af812008-10-24 19:21:13208 }
209
dchengfe61fca2014-10-22 02:29:52210 bool OnMessageReceived(const Message& message) override {
initial.commit09911bf2008-07-26 23:55:29211 IPC_BEGIN_MESSAGE_MAP(Worker, message)
[email protected]3cdb7af812008-10-24 19:21:13212 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_Double, OnDoubleDelay)
initial.commit09911bf2008-07-26 23:55:29213 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_AnswerToLife,
214 OnAnswerDelay)
[email protected]ac0efda2009-10-14 16:22:02215 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelNestedTestMsg_String,
216 OnNestedTestMsg)
initial.commit09911bf2008-07-26 23:55:29217 IPC_END_MESSAGE_MAP()
[email protected]a95986a82010-12-24 06:19:28218 return true;
initial.commit09911bf2008-07-26 23:55:29219 }
220
[email protected]fd0a773a2013-04-30 20:55:03221 void StartThread(base::Thread* thread, base::MessageLoop::Type type) {
[email protected]ab820df2008-08-26 05:55:10222 base::Thread::Options options;
[email protected]17b89142008-11-07 21:52:15223 options.message_loop_type = type;
[email protected]ab820df2008-08-26 05:55:10224 thread->StartWithOptions(options);
225 }
226
[email protected]aa96ae772009-01-20 22:08:15227 scoped_ptr<WaitableEvent> done_;
228 scoped_ptr<WaitableEvent> channel_created_;
[email protected]9a3a293b2009-06-04 22:28:16229 std::string channel_name_;
initial.commit09911bf2008-07-26 23:55:29230 Channel::Mode mode_;
231 scoped_ptr<SyncChannel> channel_;
[email protected]ab820df2008-08-26 05:55:10232 base::Thread ipc_thread_;
233 base::Thread listener_thread_;
234 base::Thread* overrided_thread_;
initial.commit09911bf2008-07-26 23:55:29235
[email protected]8930d472009-02-21 08:05:28236 base::WaitableEvent shutdown_event_;
237
[email protected]bf2a9092013-01-08 06:09:07238 bool is_shutdown_;
239
[email protected]73a797fb2010-06-07 02:10:18240 DISALLOW_COPY_AND_ASSIGN(Worker);
initial.commit09911bf2008-07-26 23:55:29241};
242
243
244// Starts the test with the given workers. This function deletes the workers
245// when it's done.
246void RunTest(std::vector<Worker*> workers) {
initial.commit09911bf2008-07-26 23:55:29247 // First we create the workers that are channel servers, or else the other
248 // workers' channel initialization might fail because the pipe isn't created..
249 for (size_t i = 0; i < workers.size(); ++i) {
[email protected]1707726c2011-02-03 20:35:09250 if (workers[i]->mode() & Channel::MODE_SERVER_FLAG) {
initial.commit09911bf2008-07-26 23:55:29251 workers[i]->Start();
252 workers[i]->WaitForChannelCreation();
253 }
254 }
255
256 // now create the clients
257 for (size_t i = 0; i < workers.size(); ++i) {
[email protected]1707726c2011-02-03 20:35:09258 if (workers[i]->mode() & Channel::MODE_CLIENT_FLAG)
initial.commit09911bf2008-07-26 23:55:29259 workers[i]->Start();
260 }
261
262 // wait for all the workers to finish
initial.commit09911bf2008-07-26 23:55:29263 for (size_t i = 0; i < workers.size(); ++i)
[email protected]aa96ae772009-01-20 22:08:15264 workers[i]->done_event()->Wait();
initial.commit09911bf2008-07-26 23:55:29265
[email protected]bf2a9092013-01-08 06:09:07266 for (size_t i = 0; i < workers.size(); ++i) {
267 workers[i]->Shutdown();
268 delete workers[i];
269 }
initial.commit09911bf2008-07-26 23:55:29270}
271
[email protected]9629c0e2009-02-04 23:16:29272class IPCSyncChannelTest : public testing::Test {
273 private:
[email protected]fd0a773a2013-04-30 20:55:03274 base::MessageLoop message_loop_;
[email protected]9629c0e2009-02-04 23:16:29275};
276
[email protected]2a3aa7b52013-01-11 20:56:22277//------------------------------------------------------------------------------
[email protected]dd3eac22008-08-26 07:28:34278
initial.commit09911bf2008-07-26 23:55:29279class SimpleServer : public Worker {
280 public:
erikchen99fbfc662016-04-08 22:37:48281 SimpleServer(bool pump_during_send, const std::string& channel_name)
282 : Worker(Channel::MODE_SERVER, "simpler_server", channel_name),
283 pump_during_send_(pump_during_send) {}
dchengfe61fca2014-10-22 02:29:52284 void Run() override {
[email protected]5855f1d2014-04-16 16:50:43285 SendAnswerToLife(pump_during_send_, true);
initial.commit09911bf2008-07-26 23:55:29286 Done();
287 }
[email protected]3cdb7af812008-10-24 19:21:13288
289 bool pump_during_send_;
initial.commit09911bf2008-07-26 23:55:29290};
291
292class SimpleClient : public Worker {
293 public:
erikchen99fbfc662016-04-08 22:37:48294 explicit SimpleClient(const std::string& channel_name)
295 : Worker(Channel::MODE_CLIENT, "simple_client", channel_name) {}
initial.commit09911bf2008-07-26 23:55:29296
dchengfe61fca2014-10-22 02:29:52297 void OnAnswer(int* answer) override {
initial.commit09911bf2008-07-26 23:55:29298 *answer = 42;
299 Done();
300 }
301};
302
[email protected]3cdb7af812008-10-24 19:21:13303void Simple(bool pump_during_send) {
initial.commit09911bf2008-07-26 23:55:29304 std::vector<Worker*> workers;
erikchen99fbfc662016-04-08 22:37:48305 workers.push_back(new SimpleServer(pump_during_send, "Simple"));
306 workers.push_back(new SimpleClient("Simple"));
initial.commit09911bf2008-07-26 23:55:29307 RunTest(workers);
308}
309
tfarina8514f0d2015-07-28 14:41:47310#if defined(OS_ANDROID)
311#define MAYBE_Simple DISABLED_Simple
312#else
313#define MAYBE_Simple Simple
314#endif
[email protected]3cdb7af812008-10-24 19:21:13315// Tests basic synchronous call
tfarina8514f0d2015-07-28 14:41:47316TEST_F(IPCSyncChannelTest, MAYBE_Simple) {
[email protected]3cdb7af812008-10-24 19:21:13317 Simple(false);
318 Simple(true);
319}
initial.commit09911bf2008-07-26 23:55:29320
[email protected]2a3aa7b52013-01-11 20:56:22321//------------------------------------------------------------------------------
[email protected]dd3eac22008-08-26 07:28:34322
[email protected]952394af2011-11-16 01:06:46323// Worker classes which override how the sync channel is created to use the
324// two-step initialization (calling the lightweight constructor and then
325// ChannelProxy::Init separately) process.
326class TwoStepServer : public Worker {
327 public:
erikchen99fbfc662016-04-08 22:37:48328 TwoStepServer(bool create_pipe_now, const std::string& channel_name)
329 : Worker(Channel::MODE_SERVER, "simpler_server", channel_name),
330 create_pipe_now_(create_pipe_now) {}
[email protected]952394af2011-11-16 01:06:46331
dchengfe61fca2014-10-22 02:29:52332 void Run() override {
[email protected]5855f1d2014-04-16 16:50:43333 SendAnswerToLife(false, true);
[email protected]952394af2011-11-16 01:06:46334 Done();
335 }
336
dchengfe61fca2014-10-22 02:29:52337 SyncChannel* CreateChannel() override {
[email protected]fca876a12014-06-05 16:15:38338 SyncChannel* channel =
339 SyncChannel::Create(channel_name(), mode(), this,
skyostile687bdff2015-05-12 11:29:21340 ipc_thread().task_runner().get(), create_pipe_now_,
erikchen30dc2812015-09-24 03:26:38341 shutdown_event())
342 .release();
[email protected]952394af2011-11-16 01:06:46343 return channel;
344 }
345
346 bool create_pipe_now_;
347};
348
349class TwoStepClient : public Worker {
350 public:
erikchen99fbfc662016-04-08 22:37:48351 TwoStepClient(bool create_pipe_now, const std::string& channel_name)
352 : Worker(Channel::MODE_CLIENT, "simple_client", channel_name),
353 create_pipe_now_(create_pipe_now) {}
[email protected]952394af2011-11-16 01:06:46354
dchengfe61fca2014-10-22 02:29:52355 void OnAnswer(int* answer) override {
[email protected]952394af2011-11-16 01:06:46356 *answer = 42;
357 Done();
358 }
359
dchengfe61fca2014-10-22 02:29:52360 SyncChannel* CreateChannel() override {
[email protected]fca876a12014-06-05 16:15:38361 SyncChannel* channel =
362 SyncChannel::Create(channel_name(), mode(), this,
skyostile687bdff2015-05-12 11:29:21363 ipc_thread().task_runner().get(), create_pipe_now_,
erikchen30dc2812015-09-24 03:26:38364 shutdown_event())
365 .release();
[email protected]952394af2011-11-16 01:06:46366 return channel;
367 }
368
369 bool create_pipe_now_;
370};
371
372void TwoStep(bool create_server_pipe_now, bool create_client_pipe_now) {
373 std::vector<Worker*> workers;
erikchen99fbfc662016-04-08 22:37:48374 workers.push_back(new TwoStepServer(create_server_pipe_now, "TwoStep"));
375 workers.push_back(new TwoStepClient(create_client_pipe_now, "TwoStep"));
[email protected]952394af2011-11-16 01:06:46376 RunTest(workers);
377}
378
[email protected]952394af2011-11-16 01:06:46379// Tests basic two-step initialization, where you call the lightweight
380// constructor then Init.
381TEST_F(IPCSyncChannelTest, TwoStepInitialization) {
382 TwoStep(false, false);
383 TwoStep(false, true);
384 TwoStep(true, false);
385 TwoStep(true, true);
386}
387
[email protected]2a3aa7b52013-01-11 20:56:22388//------------------------------------------------------------------------------
[email protected]952394af2011-11-16 01:06:46389
initial.commit09911bf2008-07-26 23:55:29390class DelayClient : public Worker {
391 public:
erikchen99fbfc662016-04-08 22:37:48392 explicit DelayClient(const std::string& channel_name)
393 : Worker(Channel::MODE_CLIENT, "delay_client", channel_name) {}
initial.commit09911bf2008-07-26 23:55:29394
dchengfe61fca2014-10-22 02:29:52395 void OnAnswerDelay(Message* reply_msg) override {
initial.commit09911bf2008-07-26 23:55:29396 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42);
397 Send(reply_msg);
398 Done();
399 }
400};
401
[email protected]3cdb7af812008-10-24 19:21:13402void DelayReply(bool pump_during_send) {
initial.commit09911bf2008-07-26 23:55:29403 std::vector<Worker*> workers;
erikchen99fbfc662016-04-08 22:37:48404 workers.push_back(new SimpleServer(pump_during_send, "DelayReply"));
405 workers.push_back(new DelayClient("DelayReply"));
initial.commit09911bf2008-07-26 23:55:29406 RunTest(workers);
407}
408
[email protected]3cdb7af812008-10-24 19:21:13409// Tests that asynchronous replies work
410TEST_F(IPCSyncChannelTest, DelayReply) {
411 DelayReply(false);
412 DelayReply(true);
413}
initial.commit09911bf2008-07-26 23:55:29414
[email protected]2a3aa7b52013-01-11 20:56:22415//------------------------------------------------------------------------------
[email protected]dd3eac22008-08-26 07:28:34416
initial.commit09911bf2008-07-26 23:55:29417class NoHangServer : public Worker {
418 public:
erikchen99fbfc662016-04-08 22:37:48419 NoHangServer(WaitableEvent* got_first_reply,
420 bool pump_during_send,
421 const std::string& channel_name)
422 : Worker(Channel::MODE_SERVER, "no_hang_server", channel_name),
[email protected]3cdb7af812008-10-24 19:21:13423 got_first_reply_(got_first_reply),
erikchen99fbfc662016-04-08 22:37:48424 pump_during_send_(pump_during_send) {}
dchengfe61fca2014-10-22 02:29:52425 void Run() override {
[email protected]5855f1d2014-04-16 16:50:43426 SendAnswerToLife(pump_during_send_, true);
[email protected]aa96ae772009-01-20 22:08:15427 got_first_reply_->Signal();
initial.commit09911bf2008-07-26 23:55:29428
[email protected]5855f1d2014-04-16 16:50:43429 SendAnswerToLife(pump_during_send_, false);
initial.commit09911bf2008-07-26 23:55:29430 Done();
431 }
432
[email protected]aa96ae772009-01-20 22:08:15433 WaitableEvent* got_first_reply_;
[email protected]3cdb7af812008-10-24 19:21:13434 bool pump_during_send_;
initial.commit09911bf2008-07-26 23:55:29435};
436
437class NoHangClient : public Worker {
438 public:
erikchen99fbfc662016-04-08 22:37:48439 NoHangClient(WaitableEvent* got_first_reply, const std::string& channel_name)
440 : Worker(Channel::MODE_CLIENT, "no_hang_client", channel_name),
441 got_first_reply_(got_first_reply) {}
initial.commit09911bf2008-07-26 23:55:29442
dchengfe61fca2014-10-22 02:29:52443 void OnAnswerDelay(Message* reply_msg) override {
initial.commit09911bf2008-07-26 23:55:29444 // Use the DELAY_REPLY macro so that we can force the reply to be sent
445 // before this function returns (when the channel will be reset).
446 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42);
447 Send(reply_msg);
448 got_first_reply_->Wait();
449 CloseChannel();
450 Done();
451 }
452
[email protected]aa96ae772009-01-20 22:08:15453 WaitableEvent* got_first_reply_;
initial.commit09911bf2008-07-26 23:55:29454};
455
[email protected]3cdb7af812008-10-24 19:21:13456void NoHang(bool pump_during_send) {
[email protected]aa96ae772009-01-20 22:08:15457 WaitableEvent got_first_reply(false, false);
initial.commit09911bf2008-07-26 23:55:29458 std::vector<Worker*> workers;
erikchen99fbfc662016-04-08 22:37:48459 workers.push_back(
460 new NoHangServer(&got_first_reply, pump_during_send, "NoHang"));
461 workers.push_back(new NoHangClient(&got_first_reply, "NoHang"));
initial.commit09911bf2008-07-26 23:55:29462 RunTest(workers);
463}
464
[email protected]3cdb7af812008-10-24 19:21:13465// Tests that caller doesn't hang if receiver dies
466TEST_F(IPCSyncChannelTest, NoHang) {
467 NoHang(false);
468 NoHang(true);
469}
initial.commit09911bf2008-07-26 23:55:29470
[email protected]2a3aa7b52013-01-11 20:56:22471//------------------------------------------------------------------------------
[email protected]dd3eac22008-08-26 07:28:34472
[email protected]3cdb7af812008-10-24 19:21:13473class UnblockServer : public Worker {
initial.commit09911bf2008-07-26 23:55:29474 public:
erikchen99fbfc662016-04-08 22:37:48475 UnblockServer(bool pump_during_send,
476 bool delete_during_send,
477 const std::string& channel_name)
478 : Worker(Channel::MODE_SERVER, "unblock_server", channel_name),
479 pump_during_send_(pump_during_send),
480 delete_during_send_(delete_during_send) {}
dchengfe61fca2014-10-22 02:29:52481 void Run() override {
[email protected]9eec2252009-12-01 02:34:18482 if (delete_during_send_) {
483 // Use custom code since race conditions mean the answer may or may not be
484 // available.
485 int answer = 0;
486 SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer);
487 if (pump_during_send_)
488 msg->EnableMessagePumping();
489 Send(msg);
490 } else {
[email protected]5855f1d2014-04-16 16:50:43491 SendAnswerToLife(pump_during_send_, true);
[email protected]9eec2252009-12-01 02:34:18492 }
initial.commit09911bf2008-07-26 23:55:29493 Done();
494 }
495
dchengfe61fca2014-10-22 02:29:52496 void OnDoubleDelay(int in, Message* reply_msg) override {
[email protected]9eec2252009-12-01 02:34:18497 SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, in * 2);
498 Send(reply_msg);
499 if (delete_during_send_)
500 ResetChannel();
initial.commit09911bf2008-07-26 23:55:29501 }
[email protected]3cdb7af812008-10-24 19:21:13502
503 bool pump_during_send_;
[email protected]9eec2252009-12-01 02:34:18504 bool delete_during_send_;
initial.commit09911bf2008-07-26 23:55:29505};
506
[email protected]3cdb7af812008-10-24 19:21:13507class UnblockClient : public Worker {
initial.commit09911bf2008-07-26 23:55:29508 public:
erikchen99fbfc662016-04-08 22:37:48509 UnblockClient(bool pump_during_send, const std::string& channel_name)
510 : Worker(Channel::MODE_CLIENT, "unblock_client", channel_name),
511 pump_during_send_(pump_during_send) {}
initial.commit09911bf2008-07-26 23:55:29512
dchengfe61fca2014-10-22 02:29:52513 void OnAnswer(int* answer) override {
[email protected]4df10d612008-11-12 00:38:26514 SendDouble(pump_during_send_, true);
515 *answer = 42;
initial.commit09911bf2008-07-26 23:55:29516 Done();
517 }
[email protected]3cdb7af812008-10-24 19:21:13518
519 bool pump_during_send_;
initial.commit09911bf2008-07-26 23:55:29520};
521
[email protected]9eec2252009-12-01 02:34:18522void Unblock(bool server_pump, bool client_pump, bool delete_during_send) {
[email protected]3cdb7af812008-10-24 19:21:13523 std::vector<Worker*> workers;
erikchen99fbfc662016-04-08 22:37:48524 workers.push_back(
525 new UnblockServer(server_pump, delete_during_send, "Unblock"));
526 workers.push_back(new UnblockClient(client_pump, "Unblock"));
[email protected]3cdb7af812008-10-24 19:21:13527 RunTest(workers);
528}
529
initial.commit09911bf2008-07-26 23:55:29530// Tests that the caller unblocks to answer a sync message from the receiver.
[email protected]3cdb7af812008-10-24 19:21:13531TEST_F(IPCSyncChannelTest, Unblock) {
[email protected]9eec2252009-12-01 02:34:18532 Unblock(false, false, false);
533 Unblock(false, true, false);
534 Unblock(true, false, false);
535 Unblock(true, true, false);
536}
537
[email protected]2a3aa7b52013-01-11 20:56:22538//------------------------------------------------------------------------------
[email protected]9eec2252009-12-01 02:34:18539
tfarina8514f0d2015-07-28 14:41:47540#if defined(OS_ANDROID)
541#define MAYBE_ChannelDeleteDuringSend DISABLED_ChannelDeleteDuringSend
542#else
543#define MAYBE_ChannelDeleteDuringSend ChannelDeleteDuringSend
544#endif
[email protected]c9e0c7332011-05-13 22:42:41545// Tests that the the SyncChannel object can be deleted during a Send.
tfarina8514f0d2015-07-28 14:41:47546TEST_F(IPCSyncChannelTest, MAYBE_ChannelDeleteDuringSend) {
[email protected]9eec2252009-12-01 02:34:18547 Unblock(false, false, true);
548 Unblock(false, true, true);
549 Unblock(true, false, true);
550 Unblock(true, true, true);
[email protected]3cdb7af812008-10-24 19:21:13551}
552
[email protected]2a3aa7b52013-01-11 20:56:22553//------------------------------------------------------------------------------
[email protected]3cdb7af812008-10-24 19:21:13554
555class RecursiveServer : public Worker {
556 public:
erikchen99fbfc662016-04-08 22:37:48557 RecursiveServer(bool expected_send_result,
558 bool pump_first,
559 bool pump_second,
560 const std::string& channel_name)
561 : Worker(Channel::MODE_SERVER, "recursive_server", channel_name),
[email protected]e7e38032011-07-26 17:25:25562 expected_send_result_(expected_send_result),
erikchen99fbfc662016-04-08 22:37:48563 pump_first_(pump_first),
564 pump_second_(pump_second) {}
dchengfe61fca2014-10-22 02:29:52565 void Run() override {
[email protected]4df10d612008-11-12 00:38:26566 SendDouble(pump_first_, expected_send_result_);
[email protected]3cdb7af812008-10-24 19:21:13567 Done();
568 }
569
dchengfe61fca2014-10-22 02:29:52570 void OnDouble(int in, int* out) override {
[email protected]4df10d612008-11-12 00:38:26571 *out = in * 2;
[email protected]5855f1d2014-04-16 16:50:43572 SendAnswerToLife(pump_second_, expected_send_result_);
[email protected]3cdb7af812008-10-24 19:21:13573 }
574
575 bool expected_send_result_, pump_first_, pump_second_;
576};
577
578class RecursiveClient : public Worker {
579 public:
erikchen99fbfc662016-04-08 22:37:48580 RecursiveClient(bool pump_during_send,
581 bool close_channel,
582 const std::string& channel_name)
583 : Worker(Channel::MODE_CLIENT, "recursive_client", channel_name),
584 pump_during_send_(pump_during_send),
585 close_channel_(close_channel) {}
[email protected]3cdb7af812008-10-24 19:21:13586
dchengfe61fca2014-10-22 02:29:52587 void OnDoubleDelay(int in, Message* reply_msg) override {
[email protected]4df10d612008-11-12 00:38:26588 SendDouble(pump_during_send_, !close_channel_);
[email protected]c690a182008-10-24 23:10:32589 if (close_channel_) {
590 delete reply_msg;
591 } else {
[email protected]3cdb7af812008-10-24 19:21:13592 SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, in * 2);
593 Send(reply_msg);
594 }
595 Done();
596 }
597
dchengfe61fca2014-10-22 02:29:52598 void OnAnswerDelay(Message* reply_msg) override {
[email protected]3cdb7af812008-10-24 19:21:13599 if (close_channel_) {
[email protected]c690a182008-10-24 23:10:32600 delete reply_msg;
[email protected]3cdb7af812008-10-24 19:21:13601 CloseChannel();
602 } else {
603 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42);
604 Send(reply_msg);
605 }
606 }
607
608 bool pump_during_send_, close_channel_;
609};
610
611void Recursive(
612 bool server_pump_first, bool server_pump_second, bool client_pump) {
initial.commit09911bf2008-07-26 23:55:29613 std::vector<Worker*> workers;
erikchen99fbfc662016-04-08 22:37:48614 workers.push_back(new RecursiveServer(true, server_pump_first,
615 server_pump_second, "Recursive"));
616 workers.push_back(new RecursiveClient(client_pump, false, "Recursive"));
initial.commit09911bf2008-07-26 23:55:29617 RunTest(workers);
618}
619
[email protected]3cdb7af812008-10-24 19:21:13620// Tests a server calling Send while another Send is pending.
621TEST_F(IPCSyncChannelTest, Recursive) {
622 Recursive(false, false, false);
623 Recursive(false, false, true);
624 Recursive(false, true, false);
625 Recursive(false, true, true);
626 Recursive(true, false, false);
627 Recursive(true, false, true);
628 Recursive(true, true, false);
629 Recursive(true, true, true);
630}
631
[email protected]2a3aa7b52013-01-11 20:56:22632//------------------------------------------------------------------------------
[email protected]3cdb7af812008-10-24 19:21:13633
634void RecursiveNoHang(
635 bool server_pump_first, bool server_pump_second, bool client_pump) {
636 std::vector<Worker*> workers;
erikchen99fbfc662016-04-08 22:37:48637 workers.push_back(new RecursiveServer(false, server_pump_first,
638 server_pump_second, "RecursiveNoHang"));
639 workers.push_back(new RecursiveClient(client_pump, true, "RecursiveNoHang"));
[email protected]3cdb7af812008-10-24 19:21:13640 RunTest(workers);
641}
642
[email protected]3cdb7af812008-10-24 19:21:13643// Tests that if a caller makes a sync call during an existing sync call and
644// the receiver dies, neither of the Send() calls hang.
645TEST_F(IPCSyncChannelTest, RecursiveNoHang) {
646 RecursiveNoHang(false, false, false);
647 RecursiveNoHang(false, false, true);
648 RecursiveNoHang(false, true, false);
649 RecursiveNoHang(false, true, true);
650 RecursiveNoHang(true, false, false);
651 RecursiveNoHang(true, false, true);
652 RecursiveNoHang(true, true, false);
653 RecursiveNoHang(true, true, true);
654}
initial.commit09911bf2008-07-26 23:55:29655
[email protected]2a3aa7b52013-01-11 20:56:22656//------------------------------------------------------------------------------
[email protected]dd3eac22008-08-26 07:28:34657
initial.commit09911bf2008-07-26 23:55:29658class MultipleServer1 : public Worker {
659 public:
[email protected]b7243c42010-07-23 05:23:13660 explicit MultipleServer1(bool pump_during_send)
[email protected]9a3a293b2009-06-04 22:28:16661 : Worker("test_channel1", Channel::MODE_SERVER),
[email protected]3cdb7af812008-10-24 19:21:13662 pump_during_send_(pump_during_send) { }
663
dchengfe61fca2014-10-22 02:29:52664 void Run() override {
[email protected]4df10d612008-11-12 00:38:26665 SendDouble(pump_during_send_, true);
initial.commit09911bf2008-07-26 23:55:29666 Done();
667 }
[email protected]3cdb7af812008-10-24 19:21:13668
669 bool pump_during_send_;
initial.commit09911bf2008-07-26 23:55:29670};
671
672class MultipleClient1 : public Worker {
673 public:
[email protected]aa96ae772009-01-20 22:08:15674 MultipleClient1(WaitableEvent* client1_msg_received,
675 WaitableEvent* client1_can_reply) :
[email protected]9a3a293b2009-06-04 22:28:16676 Worker("test_channel1", Channel::MODE_CLIENT),
initial.commit09911bf2008-07-26 23:55:29677 client1_msg_received_(client1_msg_received),
678 client1_can_reply_(client1_can_reply) { }
679
dchengfe61fca2014-10-22 02:29:52680 void OnDouble(int in, int* out) override {
[email protected]aa96ae772009-01-20 22:08:15681 client1_msg_received_->Signal();
initial.commit09911bf2008-07-26 23:55:29682 *out = in * 2;
683 client1_can_reply_->Wait();
684 Done();
685 }
686
687 private:
[email protected]aa96ae772009-01-20 22:08:15688 WaitableEvent *client1_msg_received_, *client1_can_reply_;
initial.commit09911bf2008-07-26 23:55:29689};
690
691class MultipleServer2 : public Worker {
692 public:
[email protected]9a3a293b2009-06-04 22:28:16693 MultipleServer2() : Worker("test_channel2", Channel::MODE_SERVER) { }
initial.commit09911bf2008-07-26 23:55:29694
dchengfe61fca2014-10-22 02:29:52695 void OnAnswer(int* result) override {
initial.commit09911bf2008-07-26 23:55:29696 *result = 42;
697 Done();
698 }
699};
700
701class MultipleClient2 : public Worker {
702 public:
[email protected]3cdb7af812008-10-24 19:21:13703 MultipleClient2(
[email protected]aa96ae772009-01-20 22:08:15704 WaitableEvent* client1_msg_received, WaitableEvent* client1_can_reply,
[email protected]3cdb7af812008-10-24 19:21:13705 bool pump_during_send)
[email protected]9a3a293b2009-06-04 22:28:16706 : Worker("test_channel2", Channel::MODE_CLIENT),
initial.commit09911bf2008-07-26 23:55:29707 client1_msg_received_(client1_msg_received),
[email protected]3cdb7af812008-10-24 19:21:13708 client1_can_reply_(client1_can_reply),
709 pump_during_send_(pump_during_send) { }
initial.commit09911bf2008-07-26 23:55:29710
dchengfe61fca2014-10-22 02:29:52711 void Run() override {
initial.commit09911bf2008-07-26 23:55:29712 client1_msg_received_->Wait();
[email protected]5855f1d2014-04-16 16:50:43713 SendAnswerToLife(pump_during_send_, true);
[email protected]aa96ae772009-01-20 22:08:15714 client1_can_reply_->Signal();
initial.commit09911bf2008-07-26 23:55:29715 Done();
716 }
717
718 private:
[email protected]aa96ae772009-01-20 22:08:15719 WaitableEvent *client1_msg_received_, *client1_can_reply_;
[email protected]3cdb7af812008-10-24 19:21:13720 bool pump_during_send_;
initial.commit09911bf2008-07-26 23:55:29721};
722
[email protected]3cdb7af812008-10-24 19:21:13723void Multiple(bool server_pump, bool client_pump) {
initial.commit09911bf2008-07-26 23:55:29724 std::vector<Worker*> workers;
725
726 // A shared worker thread so that server1 and server2 run on one thread.
[email protected]ab820df2008-08-26 05:55:10727 base::Thread worker_thread("Multiple");
[email protected]6314e6f62009-07-15 16:07:14728 ASSERT_TRUE(worker_thread.Start());
initial.commit09911bf2008-07-26 23:55:29729
730 // Server1 sends a sync msg to client1, which blocks the reply until
731 // server2 (which runs on the same worker thread as server1) responds
732 // to a sync msg from client2.
[email protected]aa96ae772009-01-20 22:08:15733 WaitableEvent client1_msg_received(false, false);
734 WaitableEvent client1_can_reply(false, false);
initial.commit09911bf2008-07-26 23:55:29735
736 Worker* worker;
737
738 worker = new MultipleServer2();
739 worker->OverrideThread(&worker_thread);
740 workers.push_back(worker);
741
742 worker = new MultipleClient2(
[email protected]3cdb7af812008-10-24 19:21:13743 &client1_msg_received, &client1_can_reply, client_pump);
initial.commit09911bf2008-07-26 23:55:29744 workers.push_back(worker);
745
[email protected]3cdb7af812008-10-24 19:21:13746 worker = new MultipleServer1(server_pump);
initial.commit09911bf2008-07-26 23:55:29747 worker->OverrideThread(&worker_thread);
748 workers.push_back(worker);
749
750 worker = new MultipleClient1(
751 &client1_msg_received, &client1_can_reply);
752 workers.push_back(worker);
753
754 RunTest(workers);
755}
756
[email protected]3cdb7af812008-10-24 19:21:13757// Tests that multiple SyncObjects on the same listener thread can unblock each
758// other.
759TEST_F(IPCSyncChannelTest, Multiple) {
760 Multiple(false, false);
761 Multiple(false, true);
762 Multiple(true, false);
763 Multiple(true, true);
764}
initial.commit09911bf2008-07-26 23:55:29765
[email protected]2a3aa7b52013-01-11 20:56:22766//------------------------------------------------------------------------------
[email protected]dd3eac22008-08-26 07:28:34767
[email protected]ac0efda2009-10-14 16:22:02768// This class provides server side functionality to test the case where
769// multiple sync channels are in use on the same thread on the client and
770// nested calls are issued.
771class QueuedReplyServer : public Worker {
initial.commit09911bf2008-07-26 23:55:29772 public:
[email protected]b7243c42010-07-23 05:23:13773 QueuedReplyServer(base::Thread* listener_thread,
774 const std::string& channel_name,
775 const std::string& reply_text)
[email protected]ac0efda2009-10-14 16:22:02776 : Worker(channel_name, Channel::MODE_SERVER),
777 reply_text_(reply_text) {
778 Worker::OverrideThread(listener_thread);
initial.commit09911bf2008-07-26 23:55:29779 }
[email protected]3cdb7af812008-10-24 19:21:13780
dchengfe61fca2014-10-22 02:29:52781 void OnNestedTestMsg(Message* reply_msg) override {
[email protected]2a9d601b2010-10-19 23:50:00782 VLOG(1) << __FUNCTION__ << " Sending reply: " << reply_text_;
783 SyncChannelNestedTestMsg_String::WriteReplyParams(reply_msg, reply_text_);
[email protected]ac0efda2009-10-14 16:22:02784 Send(reply_msg);
initial.commit09911bf2008-07-26 23:55:29785 Done();
786 }
787
788 private:
[email protected]ac0efda2009-10-14 16:22:02789 std::string reply_text_;
initial.commit09911bf2008-07-26 23:55:29790};
791
[email protected]ac0efda2009-10-14 16:22:02792// The QueuedReplyClient class provides functionality to test the case where
793// multiple sync channels are in use on the same thread and they make nested
794// sync calls, i.e. while the first channel waits for a response it makes a
795// sync call on another channel.
796// The callstack should unwind correctly, i.e. the outermost call should
797// complete first, and so on.
798class QueuedReplyClient : public Worker {
initial.commit09911bf2008-07-26 23:55:29799 public:
[email protected]ac0efda2009-10-14 16:22:02800 QueuedReplyClient(base::Thread* listener_thread,
801 const std::string& channel_name,
802 const std::string& expected_text,
803 bool pump_during_send)
804 : Worker(channel_name, Channel::MODE_CLIENT),
[email protected]7ee1a44c2010-07-23 14:18:59805 pump_during_send_(pump_during_send),
806 expected_text_(expected_text) {
[email protected]ac0efda2009-10-14 16:22:02807 Worker::OverrideThread(listener_thread);
808 }
initial.commit09911bf2008-07-26 23:55:29809
dchengfe61fca2014-10-22 02:29:52810 void Run() override {
[email protected]ac0efda2009-10-14 16:22:02811 std::string response;
812 SyncMessage* msg = new SyncChannelNestedTestMsg_String(&response);
813 if (pump_during_send_)
814 msg->EnableMessagePumping();
815 bool result = Send(msg);
816 DCHECK(result);
[email protected]9eec2252009-12-01 02:34:18817 DCHECK_EQ(response, expected_text_);
initial.commit09911bf2008-07-26 23:55:29818
[email protected]2a9d601b2010-10-19 23:50:00819 VLOG(1) << __FUNCTION__ << " Received reply: " << response;
initial.commit09911bf2008-07-26 23:55:29820 Done();
821 }
822
[email protected]ac0efda2009-10-14 16:22:02823 private:
[email protected]3cdb7af812008-10-24 19:21:13824 bool pump_during_send_;
[email protected]ac0efda2009-10-14 16:22:02825 std::string expected_text_;
initial.commit09911bf2008-07-26 23:55:29826};
827
[email protected]ac0efda2009-10-14 16:22:02828void QueuedReply(bool client_pump) {
initial.commit09911bf2008-07-26 23:55:29829 std::vector<Worker*> workers;
830
[email protected]ac0efda2009-10-14 16:22:02831 // A shared worker thread for servers
832 base::Thread server_worker_thread("QueuedReply_ServerListener");
833 ASSERT_TRUE(server_worker_thread.Start());
initial.commit09911bf2008-07-26 23:55:29834
[email protected]ac0efda2009-10-14 16:22:02835 base::Thread client_worker_thread("QueuedReply_ClientListener");
836 ASSERT_TRUE(client_worker_thread.Start());
initial.commit09911bf2008-07-26 23:55:29837
838 Worker* worker;
839
[email protected]ac0efda2009-10-14 16:22:02840 worker = new QueuedReplyServer(&server_worker_thread,
841 "QueuedReply_Server1",
842 "Got first message");
initial.commit09911bf2008-07-26 23:55:29843 workers.push_back(worker);
844
[email protected]ac0efda2009-10-14 16:22:02845 worker = new QueuedReplyServer(&server_worker_thread,
846 "QueuedReply_Server2",
847 "Got second message");
initial.commit09911bf2008-07-26 23:55:29848 workers.push_back(worker);
849
[email protected]ac0efda2009-10-14 16:22:02850 worker = new QueuedReplyClient(&client_worker_thread,
851 "QueuedReply_Server1",
852 "Got first message",
853 client_pump);
initial.commit09911bf2008-07-26 23:55:29854 workers.push_back(worker);
855
[email protected]ac0efda2009-10-14 16:22:02856 worker = new QueuedReplyClient(&client_worker_thread,
857 "QueuedReply_Server2",
858 "Got second message",
859 client_pump);
initial.commit09911bf2008-07-26 23:55:29860 workers.push_back(worker);
861
862 RunTest(workers);
863}
864
[email protected]3cdb7af812008-10-24 19:21:13865// While a blocking send is in progress, the listener thread might answer other
866// synchronous messages. This tests that if during the response to another
867// message the reply to the original messages comes, it is queued up correctly
868// and the original Send is unblocked later.
[email protected]ac0efda2009-10-14 16:22:02869// We also test that the send call stacks unwind correctly when the channel
870// pumps messages while waiting for a response.
[email protected]3cdb7af812008-10-24 19:21:13871TEST_F(IPCSyncChannelTest, QueuedReply) {
[email protected]ac0efda2009-10-14 16:22:02872 QueuedReply(false);
873 QueuedReply(true);
[email protected]3cdb7af812008-10-24 19:21:13874}
initial.commit09911bf2008-07-26 23:55:29875
[email protected]2a3aa7b52013-01-11 20:56:22876//------------------------------------------------------------------------------
[email protected]dd3eac22008-08-26 07:28:34877
[email protected]3cdb7af812008-10-24 19:21:13878class ChattyClient : public Worker {
initial.commit09911bf2008-07-26 23:55:29879 public:
erikchen99fbfc662016-04-08 22:37:48880 explicit ChattyClient(const std::string& channel_name)
881 : Worker(Channel::MODE_CLIENT, "chatty_client", channel_name) {}
initial.commit09911bf2008-07-26 23:55:29882
dchengfe61fca2014-10-22 02:29:52883 void OnAnswer(int* answer) override {
initial.commit09911bf2008-07-26 23:55:29884 // The PostMessage limit is 10k. Send 20% more than that.
885 const int kMessageLimit = 10000;
886 const int kMessagesToSend = kMessageLimit * 120 / 100;
887 for (int i = 0; i < kMessagesToSend; ++i) {
[email protected]4df10d612008-11-12 00:38:26888 if (!SendDouble(false, true))
initial.commit09911bf2008-07-26 23:55:29889 break;
890 }
[email protected]4df10d612008-11-12 00:38:26891 *answer = 42;
initial.commit09911bf2008-07-26 23:55:29892 Done();
893 }
894};
895
[email protected]3cdb7af812008-10-24 19:21:13896void ChattyServer(bool pump_during_send) {
897 std::vector<Worker*> workers;
erikchen99fbfc662016-04-08 22:37:48898 workers.push_back(new UnblockServer(pump_during_send, false, "ChattyServer"));
899 workers.push_back(new ChattyClient("ChattyServer"));
[email protected]3cdb7af812008-10-24 19:21:13900 RunTest(workers);
901}
902
tfarina8514f0d2015-07-28 14:41:47903#if defined(OS_ANDROID)
904// Times out.
905#define MAYBE_ChattyServer DISABLED_ChattyServer
906#else
907#define MAYBE_ChattyServer ChattyServer
908#endif
[email protected]4df10d612008-11-12 00:38:26909// Tests http://b/1093251 - that sending lots of sync messages while
initial.commit09911bf2008-07-26 23:55:29910// the receiver is waiting for a sync reply does not overflow the PostMessage
911// queue.
tfarina8514f0d2015-07-28 14:41:47912TEST_F(IPCSyncChannelTest, MAYBE_ChattyServer) {
[email protected]3cdb7af812008-10-24 19:21:13913 ChattyServer(false);
914 ChattyServer(true);
initial.commit09911bf2008-07-26 23:55:29915}
[email protected]d65cab7a2008-08-12 01:25:41916
[email protected]d65cab7a2008-08-12 01:25:41917//------------------------------------------------------------------------------
[email protected]dd3eac22008-08-26 07:28:34918
[email protected]0633e3152011-11-28 18:35:39919void NestedCallback(Worker* server) {
920 // Sleep a bit so that we wake up after the reply has been received.
[email protected]b5393332012-01-13 00:11:01921 base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(250));
[email protected]5855f1d2014-04-16 16:50:43922 server->SendAnswerToLife(true, true);
[email protected]0633e3152011-11-28 18:35:39923}
[email protected]4df10d612008-11-12 00:38:26924
[email protected]0633e3152011-11-28 18:35:39925bool timeout_occurred = false;
[email protected]4df10d612008-11-12 00:38:26926
[email protected]0633e3152011-11-28 18:35:39927void TimeoutCallback() {
928 timeout_occurred = true;
929}
[email protected]4df10d612008-11-12 00:38:26930
931class DoneEventRaceServer : public Worker {
932 public:
erikchen99fbfc662016-04-08 22:37:48933 explicit DoneEventRaceServer(const std::string& channel_name)
934 : Worker(Channel::MODE_SERVER, "done_event_race_server", channel_name) {}
[email protected]4df10d612008-11-12 00:38:26935
dchengfe61fca2014-10-22 02:29:52936 void Run() override {
skyostile687bdff2015-05-12 11:29:21937 base::ThreadTaskRunnerHandle::Get()->PostTask(
938 FROM_HERE, base::Bind(&NestedCallback, this));
939 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
940 FROM_HERE, base::Bind(&TimeoutCallback),
[email protected]5896fa042012-03-07 04:41:40941 base::TimeDelta::FromSeconds(9));
[email protected]4df10d612008-11-12 00:38:26942 // Even though we have a timeout on the Send, it will succeed since for this
943 // bug, the reply message comes back and is deserialized, however the done
944 // event wasn't set. So we indirectly use the timeout task to notice if a
945 // timeout occurred.
[email protected]5855f1d2014-04-16 16:50:43946 SendAnswerToLife(true, true);
[email protected]0633e3152011-11-28 18:35:39947 DCHECK(!timeout_occurred);
[email protected]4df10d612008-11-12 00:38:26948 Done();
949 }
950};
951
tfarina8514f0d2015-07-28 14:41:47952#if defined(OS_ANDROID)
953#define MAYBE_DoneEventRace DISABLED_DoneEventRace
954#else
955#define MAYBE_DoneEventRace DoneEventRace
956#endif
[email protected]4df10d612008-11-12 00:38:26957// Tests http://b/1474092 - that if after the done_event is set but before
958// OnObjectSignaled is called another message is sent out, then after its
959// reply comes back OnObjectSignaled will be called for the first message.
tfarina8514f0d2015-07-28 14:41:47960TEST_F(IPCSyncChannelTest, MAYBE_DoneEventRace) {
[email protected]4df10d612008-11-12 00:38:26961 std::vector<Worker*> workers;
erikchen99fbfc662016-04-08 22:37:48962 workers.push_back(new DoneEventRaceServer("DoneEventRace"));
963 workers.push_back(new SimpleClient("DoneEventRace"));
[email protected]4df10d612008-11-12 00:38:26964 RunTest(workers);
965}
[email protected]1e9499c2010-04-06 20:33:36966
[email protected]2a3aa7b52013-01-11 20:56:22967//------------------------------------------------------------------------------
[email protected]1e9499c2010-04-06 20:33:36968
[email protected]c9e0c7332011-05-13 22:42:41969class TestSyncMessageFilter : public SyncMessageFilter {
[email protected]1e9499c2010-04-06 20:33:36970 public:
skyostile687bdff2015-05-12 11:29:21971 TestSyncMessageFilter(
972 base::WaitableEvent* shutdown_event,
973 Worker* worker,
974 scoped_refptr<base::SingleThreadTaskRunner> task_runner)
rockotac64ae92f2015-08-06 00:32:29975 : SyncMessageFilter(shutdown_event, false),
[email protected]1e9499c2010-04-06 20:33:36976 worker_(worker),
skyostile687bdff2015-05-12 11:29:21977 task_runner_(task_runner) {}
[email protected]1e9499c2010-04-06 20:33:36978
dchengfe61fca2014-10-22 02:29:52979 void OnFilterAdded(Sender* sender) override {
[email protected]d1549b82014-06-13 06:07:14980 SyncMessageFilter::OnFilterAdded(sender);
skyostile687bdff2015-05-12 11:29:21981 task_runner_->PostTask(
[email protected]72b6f8e22011-11-12 21:16:41982 FROM_HERE,
983 base::Bind(&TestSyncMessageFilter::SendMessageOnHelperThread, this));
[email protected]1e9499c2010-04-06 20:33:36984 }
985
986 void SendMessageOnHelperThread() {
987 int answer = 0;
988 bool result = Send(new SyncChannelTestMsg_AnswerToLife(&answer));
989 DCHECK(result);
990 DCHECK_EQ(answer, 42);
991
992 worker_->Done();
993 }
994
[email protected]f729d15a2012-04-28 02:12:00995 private:
dchengfe61fca2014-10-22 02:29:52996 ~TestSyncMessageFilter() override {}
[email protected]f729d15a2012-04-28 02:12:00997
[email protected]1e9499c2010-04-06 20:33:36998 Worker* worker_;
skyostile687bdff2015-05-12 11:29:21999 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
[email protected]1e9499c2010-04-06 20:33:361000};
1001
1002class SyncMessageFilterServer : public Worker {
1003 public:
erikchen99fbfc662016-04-08 22:37:481004 explicit SyncMessageFilterServer(const std::string& channel_name)
1005 : Worker(Channel::MODE_SERVER,
1006 "sync_message_filter_server",
1007 channel_name),
[email protected]d4fc4d6a2012-09-08 01:24:491008 thread_("helper_thread") {
1009 base::Thread::Options options;
[email protected]fd0a773a2013-04-30 20:55:031010 options.message_loop_type = base::MessageLoop::TYPE_DEFAULT;
[email protected]d4fc4d6a2012-09-08 01:24:491011 thread_.StartWithOptions(options);
1012 filter_ = new TestSyncMessageFilter(shutdown_event(), this,
skyostile687bdff2015-05-12 11:29:211013 thread_.task_runner());
[email protected]1e9499c2010-04-06 20:33:361014 }
1015
dchengfe61fca2014-10-22 02:29:521016 void Run() override {
dchengf3076af2014-10-21 18:02:421017 channel()->AddFilter(filter_.get());
1018 }
[email protected]1e9499c2010-04-06 20:33:361019
[email protected]d4fc4d6a2012-09-08 01:24:491020 base::Thread thread_;
[email protected]1e9499c2010-04-06 20:33:361021 scoped_refptr<TestSyncMessageFilter> filter_;
1022};
1023
[email protected]87339f02010-09-02 21:45:501024// This class provides functionality to test the case that a Send on the sync
1025// channel does not crash after the channel has been closed.
1026class ServerSendAfterClose : public Worker {
1027 public:
erikchen99fbfc662016-04-08 22:37:481028 explicit ServerSendAfterClose(const std::string& channel_name)
1029 : Worker(Channel::MODE_SERVER, "simpler_server", channel_name),
1030 send_result_(true) {}
[email protected]87339f02010-09-02 21:45:501031
1032 bool SendDummy() {
skyostile687bdff2015-05-12 11:29:211033 ListenerThread()->task_runner()->PostTask(
[email protected]dcde7672012-01-06 02:37:171034 FROM_HERE, base::Bind(base::IgnoreResult(&ServerSendAfterClose::Send),
1035 this, new SyncChannelTestMsg_NoArgs));
[email protected]87339f02010-09-02 21:45:501036 return true;
1037 }
1038
1039 bool send_result() const {
1040 return send_result_;
1041 }
1042
1043 private:
dchengfe61fca2014-10-22 02:29:521044 void Run() override {
[email protected]87339f02010-09-02 21:45:501045 CloseChannel();
1046 Done();
1047 }
1048
dchengfe61fca2014-10-22 02:29:521049 bool Send(Message* msg) override {
[email protected]87339f02010-09-02 21:45:501050 send_result_ = Worker::Send(msg);
1051 Done();
1052 return send_result_;
1053 }
1054
1055 bool send_result_;
1056};
1057
[email protected]1e9499c2010-04-06 20:33:361058// Tests basic synchronous call
1059TEST_F(IPCSyncChannelTest, SyncMessageFilter) {
1060 std::vector<Worker*> workers;
erikchen99fbfc662016-04-08 22:37:481061 workers.push_back(new SyncMessageFilterServer("SyncMessageFilter"));
1062 workers.push_back(new SimpleClient("SyncMessageFilter"));
[email protected]1e9499c2010-04-06 20:33:361063 RunTest(workers);
1064}
[email protected]87339f02010-09-02 21:45:501065
1066// Test the case when the channel is closed and a Send is attempted after that.
1067TEST_F(IPCSyncChannelTest, SendAfterClose) {
erikchen99fbfc662016-04-08 22:37:481068 ServerSendAfterClose server("SendAfterClose");
[email protected]87339f02010-09-02 21:45:501069 server.Start();
1070
1071 server.done_event()->Wait();
1072 server.done_event()->Reset();
1073
1074 server.SendDummy();
1075 server.done_event()->Wait();
1076
1077 EXPECT_FALSE(server.send_result());
[email protected]bf2a9092013-01-08 06:09:071078
1079 server.Shutdown();
[email protected]87339f02010-09-02 21:45:501080}
1081
[email protected]2a3aa7b52013-01-11 20:56:221082//------------------------------------------------------------------------------
[email protected]54af05f2011-04-08 03:38:211083
1084class RestrictedDispatchServer : public Worker {
1085 public:
[email protected]298ee7d2012-03-30 21:29:301086 RestrictedDispatchServer(WaitableEvent* sent_ping_event,
1087 WaitableEvent* wait_event)
[email protected]54af05f2011-04-08 03:38:211088 : Worker("restricted_channel", Channel::MODE_SERVER),
[email protected]298ee7d2012-03-30 21:29:301089 sent_ping_event_(sent_ping_event),
1090 wait_event_(wait_event) { }
[email protected]54af05f2011-04-08 03:38:211091
1092 void OnDoPing(int ping) {
1093 // Send an asynchronous message that unblocks the caller.
[email protected]c9e0c7332011-05-13 22:42:411094 Message* msg = new SyncChannelTestMsg_Ping(ping);
[email protected]54af05f2011-04-08 03:38:211095 msg->set_unblock(true);
1096 Send(msg);
1097 // Signal the event after the message has been sent on the channel, on the
1098 // IPC thread.
skyostile687bdff2015-05-12 11:29:211099 ipc_thread().task_runner()->PostTask(
[email protected]72b6f8e22011-11-12 21:16:411100 FROM_HERE, base::Bind(&RestrictedDispatchServer::OnPingSent, this));
[email protected]54af05f2011-04-08 03:38:211101 }
1102
[email protected]298ee7d2012-03-30 21:29:301103 void OnPingTTL(int ping, int* out) {
1104 *out = ping;
1105 wait_event_->Wait();
1106 }
1107
[email protected]54af05f2011-04-08 03:38:211108 base::Thread* ListenerThread() { return Worker::ListenerThread(); }
1109
1110 private:
dchengfe61fca2014-10-22 02:29:521111 bool OnMessageReceived(const Message& message) override {
[email protected]54af05f2011-04-08 03:38:211112 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchServer, message)
1113 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs)
[email protected]298ee7d2012-03-30 21:29:301114 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_PingTTL, OnPingTTL)
[email protected]54af05f2011-04-08 03:38:211115 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, Done)
1116 IPC_END_MESSAGE_MAP()
1117 return true;
1118 }
1119
1120 void OnPingSent() {
1121 sent_ping_event_->Signal();
1122 }
1123
1124 void OnNoArgs() { }
1125 WaitableEvent* sent_ping_event_;
[email protected]298ee7d2012-03-30 21:29:301126 WaitableEvent* wait_event_;
[email protected]54af05f2011-04-08 03:38:211127};
1128
1129class NonRestrictedDispatchServer : public Worker {
1130 public:
[email protected]298ee7d2012-03-30 21:29:301131 NonRestrictedDispatchServer(WaitableEvent* signal_event)
1132 : Worker("non_restricted_channel", Channel::MODE_SERVER),
1133 signal_event_(signal_event) {}
1134
1135 base::Thread* ListenerThread() { return Worker::ListenerThread(); }
1136
1137 void OnDoPingTTL(int ping) {
1138 int value = 0;
1139 Send(new SyncChannelTestMsg_PingTTL(ping, &value));
1140 signal_event_->Signal();
1141 }
[email protected]54af05f2011-04-08 03:38:211142
1143 private:
dchengfe61fca2014-10-22 02:29:521144 bool OnMessageReceived(const Message& message) override {
[email protected]54af05f2011-04-08 03:38:211145 IPC_BEGIN_MESSAGE_MAP(NonRestrictedDispatchServer, message)
1146 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs)
1147 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, Done)
1148 IPC_END_MESSAGE_MAP()
1149 return true;
1150 }
1151
1152 void OnNoArgs() { }
[email protected]298ee7d2012-03-30 21:29:301153 WaitableEvent* signal_event_;
[email protected]54af05f2011-04-08 03:38:211154};
1155
1156class RestrictedDispatchClient : public Worker {
1157 public:
1158 RestrictedDispatchClient(WaitableEvent* sent_ping_event,
1159 RestrictedDispatchServer* server,
[email protected]298ee7d2012-03-30 21:29:301160 NonRestrictedDispatchServer* server2,
[email protected]54af05f2011-04-08 03:38:211161 int* success)
1162 : Worker("restricted_channel", Channel::MODE_CLIENT),
1163 ping_(0),
1164 server_(server),
[email protected]298ee7d2012-03-30 21:29:301165 server2_(server2),
[email protected]54af05f2011-04-08 03:38:211166 success_(success),
1167 sent_ping_event_(sent_ping_event) {}
1168
dchengfe61fca2014-10-22 02:29:521169 void Run() override {
[email protected]54af05f2011-04-08 03:38:211170 // Incoming messages from our channel should only be dispatched when we
1171 // send a message on that same channel.
[email protected]298ee7d2012-03-30 21:29:301172 channel()->SetRestrictDispatchChannelGroup(1);
[email protected]54af05f2011-04-08 03:38:211173
skyostile687bdff2015-05-12 11:29:211174 server_->ListenerThread()->task_runner()->PostTask(
[email protected]72b6f8e22011-11-12 21:16:411175 FROM_HERE, base::Bind(&RestrictedDispatchServer::OnDoPing, server_, 1));
[email protected]54af05f2011-04-08 03:38:211176 sent_ping_event_->Wait();
1177 Send(new SyncChannelTestMsg_NoArgs);
1178 if (ping_ == 1)
1179 ++*success_;
1180 else
1181 LOG(ERROR) << "Send failed to dispatch incoming message on same channel";
1182
skyostile687bdff2015-05-12 11:29:211183 non_restricted_channel_ = SyncChannel::Create(
1184 "non_restricted_channel", IPC::Channel::MODE_CLIENT, this,
erikchen30dc2812015-09-24 03:26:381185 ipc_thread().task_runner().get(), true, shutdown_event());
[email protected]54af05f2011-04-08 03:38:211186
skyostile687bdff2015-05-12 11:29:211187 server_->ListenerThread()->task_runner()->PostTask(
[email protected]72b6f8e22011-11-12 21:16:411188 FROM_HERE, base::Bind(&RestrictedDispatchServer::OnDoPing, server_, 2));
[email protected]54af05f2011-04-08 03:38:211189 sent_ping_event_->Wait();
1190 // Check that the incoming message is *not* dispatched when sending on the
1191 // non restricted channel.
1192 // TODO(piman): there is a possibility of a false positive race condition
1193 // here, if the message that was posted on the server-side end of the pipe
1194 // is not visible yet on the client side, but I don't know how to solve this
1195 // without hooking into the internals of SyncChannel. I haven't seen it in
1196 // practice (i.e. not setting SetRestrictDispatchToSameChannel does cause
1197 // the following to fail).
[email protected]298ee7d2012-03-30 21:29:301198 non_restricted_channel_->Send(new SyncChannelTestMsg_NoArgs);
[email protected]54af05f2011-04-08 03:38:211199 if (ping_ == 1)
1200 ++*success_;
1201 else
1202 LOG(ERROR) << "Send dispatched message from restricted channel";
1203
1204 Send(new SyncChannelTestMsg_NoArgs);
1205 if (ping_ == 2)
1206 ++*success_;
1207 else
1208 LOG(ERROR) << "Send failed to dispatch incoming message on same channel";
1209
[email protected]298ee7d2012-03-30 21:29:301210 // Check that the incoming message on the non-restricted channel is
1211 // dispatched when sending on the restricted channel.
skyostile687bdff2015-05-12 11:29:211212 server2_->ListenerThread()->task_runner()->PostTask(
[email protected]298ee7d2012-03-30 21:29:301213 FROM_HERE,
1214 base::Bind(&NonRestrictedDispatchServer::OnDoPingTTL, server2_, 3));
1215 int value = 0;
1216 Send(new SyncChannelTestMsg_PingTTL(4, &value));
1217 if (ping_ == 3 && value == 4)
1218 ++*success_;
1219 else
1220 LOG(ERROR) << "Send failed to dispatch message from unrestricted channel";
1221
1222 non_restricted_channel_->Send(new SyncChannelTestMsg_Done);
1223 non_restricted_channel_.reset();
[email protected]54af05f2011-04-08 03:38:211224 Send(new SyncChannelTestMsg_Done);
1225 Done();
1226 }
1227
1228 private:
dchengfe61fca2014-10-22 02:29:521229 bool OnMessageReceived(const Message& message) override {
[email protected]54af05f2011-04-08 03:38:211230 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchClient, message)
1231 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Ping, OnPing)
[email protected]298ee7d2012-03-30 21:29:301232 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_PingTTL, OnPingTTL)
[email protected]54af05f2011-04-08 03:38:211233 IPC_END_MESSAGE_MAP()
1234 return true;
1235 }
1236
1237 void OnPing(int ping) {
1238 ping_ = ping;
1239 }
1240
[email protected]298ee7d2012-03-30 21:29:301241 void OnPingTTL(int ping, IPC::Message* reply) {
1242 ping_ = ping;
1243 // This message comes from the NonRestrictedDispatchServer, we have to send
1244 // the reply back manually.
1245 SyncChannelTestMsg_PingTTL::WriteReplyParams(reply, ping);
1246 non_restricted_channel_->Send(reply);
1247 }
1248
[email protected]54af05f2011-04-08 03:38:211249 int ping_;
1250 RestrictedDispatchServer* server_;
[email protected]298ee7d2012-03-30 21:29:301251 NonRestrictedDispatchServer* server2_;
[email protected]54af05f2011-04-08 03:38:211252 int* success_;
1253 WaitableEvent* sent_ping_event_;
[email protected]298ee7d2012-03-30 21:29:301254 scoped_ptr<SyncChannel> non_restricted_channel_;
[email protected]54af05f2011-04-08 03:38:211255};
1256
[email protected]54af05f2011-04-08 03:38:211257TEST_F(IPCSyncChannelTest, RestrictedDispatch) {
1258 WaitableEvent sent_ping_event(false, false);
[email protected]298ee7d2012-03-30 21:29:301259 WaitableEvent wait_event(false, false);
[email protected]54af05f2011-04-08 03:38:211260 RestrictedDispatchServer* server =
[email protected]298ee7d2012-03-30 21:29:301261 new RestrictedDispatchServer(&sent_ping_event, &wait_event);
1262 NonRestrictedDispatchServer* server2 =
1263 new NonRestrictedDispatchServer(&wait_event);
1264
[email protected]54af05f2011-04-08 03:38:211265 int success = 0;
1266 std::vector<Worker*> workers;
[email protected]54af05f2011-04-08 03:38:211267 workers.push_back(server);
[email protected]298ee7d2012-03-30 21:29:301268 workers.push_back(server2);
1269 workers.push_back(new RestrictedDispatchClient(
1270 &sent_ping_event, server, server2, &success));
[email protected]54af05f2011-04-08 03:38:211271 RunTest(workers);
[email protected]298ee7d2012-03-30 21:29:301272 EXPECT_EQ(4, success);
[email protected]54af05f2011-04-08 03:38:211273}
[email protected]c9e0c7332011-05-13 22:42:411274
[email protected]2a3aa7b52013-01-11 20:56:221275//------------------------------------------------------------------------------
[email protected]522cc10d2012-01-11 22:39:541276
1277// This test case inspired by crbug.com/108491
1278// We create two servers that use the same ListenerThread but have
1279// SetRestrictDispatchToSameChannel set to true.
1280// We create clients, then use some specific WaitableEvent wait/signalling to
1281// ensure that messages get dispatched in a way that causes a deadlock due to
1282// a nested dispatch and an eligible message in a higher-level dispatch's
1283// delayed_queue. Specifically, we start with client1 about so send an
1284// unblocking message to server1, while the shared listener thread for the
1285// servers server1 and server2 is about to send a non-unblocking message to
1286// client1. At the same time, client2 will be about to send an unblocking
1287// message to server2. Server1 will handle the client1->server1 message by
1288// telling server2 to send a non-unblocking message to client2.
1289// What should happen is that the send to server2 should find the pending,
1290// same-context client2->server2 message to dispatch, causing client2 to
1291// unblock then handle the server2->client2 message, so that the shared
1292// servers' listener thread can then respond to the client1->server1 message.
1293// Then client1 can handle the non-unblocking server1->client1 message.
1294// The old code would end up in a state where the server2->client2 message is
1295// sent, but the client2->server2 message (which is eligible for dispatch, and
1296// which is what client2 is waiting for) is stashed in a local delayed_queue
1297// that has server1's channel context, causing a deadlock.
1298// WaitableEvents in the events array are used to:
1299// event 0: indicate to client1 that server listener is in OnDoServerTask
1300// event 1: indicate to client1 that client2 listener is in OnDoClient2Task
1301// event 2: indicate to server1 that client2 listener is in OnDoClient2Task
1302// event 3: indicate to client2 that server listener is in OnDoServerTask
1303
[email protected]522cc10d2012-01-11 22:39:541304class RestrictedDispatchDeadlockServer : public Worker {
1305 public:
1306 RestrictedDispatchDeadlockServer(int server_num,
1307 WaitableEvent* server_ready_event,
1308 WaitableEvent** events,
1309 RestrictedDispatchDeadlockServer* peer)
1310 : Worker(server_num == 1 ? "channel1" : "channel2", Channel::MODE_SERVER),
1311 server_num_(server_num),
1312 server_ready_event_(server_ready_event),
1313 events_(events),
[email protected]629ddf852012-07-20 16:17:291314 peer_(peer) { }
[email protected]522cc10d2012-01-11 22:39:541315
1316 void OnDoServerTask() {
1317 events_[3]->Signal();
1318 events_[2]->Wait();
1319 events_[0]->Signal();
1320 SendMessageToClient();
1321 }
1322
dchengfe61fca2014-10-22 02:29:521323 void Run() override {
[email protected]298ee7d2012-03-30 21:29:301324 channel()->SetRestrictDispatchChannelGroup(1);
[email protected]522cc10d2012-01-11 22:39:541325 server_ready_event_->Signal();
1326 }
1327
1328 base::Thread* ListenerThread() { return Worker::ListenerThread(); }
1329
1330 private:
dchengfe61fca2014-10-22 02:29:521331 bool OnMessageReceived(const Message& message) override {
[email protected]522cc10d2012-01-11 22:39:541332 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchDeadlockServer, message)
1333 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs)
1334 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, Done)
1335 IPC_END_MESSAGE_MAP()
1336 return true;
1337 }
1338
1339 void OnNoArgs() {
1340 if (server_num_ == 1) {
1341 DCHECK(peer_ != NULL);
1342 peer_->SendMessageToClient();
1343 }
1344 }
1345
1346 void SendMessageToClient() {
1347 Message* msg = new SyncChannelTestMsg_NoArgs;
1348 msg->set_unblock(false);
1349 DCHECK(!msg->should_unblock());
1350 Send(msg);
1351 }
1352
1353 int server_num_;
1354 WaitableEvent* server_ready_event_;
1355 WaitableEvent** events_;
1356 RestrictedDispatchDeadlockServer* peer_;
[email protected]522cc10d2012-01-11 22:39:541357};
1358
1359class RestrictedDispatchDeadlockClient2 : public Worker {
1360 public:
1361 RestrictedDispatchDeadlockClient2(RestrictedDispatchDeadlockServer* server,
1362 WaitableEvent* server_ready_event,
1363 WaitableEvent** events)
1364 : Worker("channel2", Channel::MODE_CLIENT),
[email protected]522cc10d2012-01-11 22:39:541365 server_ready_event_(server_ready_event),
1366 events_(events),
1367 received_msg_(false),
1368 received_noarg_reply_(false),
1369 done_issued_(false) {}
1370
dchengfe61fca2014-10-22 02:29:521371 void Run() override {
dchengf3076af2014-10-21 18:02:421372 server_ready_event_->Wait();
1373 }
[email protected]522cc10d2012-01-11 22:39:541374
1375 void OnDoClient2Task() {
1376 events_[3]->Wait();
1377 events_[1]->Signal();
1378 events_[2]->Signal();
1379 DCHECK(received_msg_ == false);
1380
1381 Message* message = new SyncChannelTestMsg_NoArgs;
1382 message->set_unblock(true);
1383 Send(message);
1384 received_noarg_reply_ = true;
1385 }
1386
1387 base::Thread* ListenerThread() { return Worker::ListenerThread(); }
1388 private:
dchengfe61fca2014-10-22 02:29:521389 bool OnMessageReceived(const Message& message) override {
[email protected]522cc10d2012-01-11 22:39:541390 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchDeadlockClient2, message)
1391 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs)
1392 IPC_END_MESSAGE_MAP()
1393 return true;
1394 }
1395
1396 void OnNoArgs() {
1397 received_msg_ = true;
1398 PossiblyDone();
1399 }
1400
1401 void PossiblyDone() {
1402 if (received_noarg_reply_ && received_msg_) {
1403 DCHECK(done_issued_ == false);
1404 done_issued_ = true;
1405 Send(new SyncChannelTestMsg_Done);
1406 Done();
1407 }
1408 }
1409
[email protected]522cc10d2012-01-11 22:39:541410 WaitableEvent* server_ready_event_;
1411 WaitableEvent** events_;
1412 bool received_msg_;
1413 bool received_noarg_reply_;
1414 bool done_issued_;
1415};
1416
1417class RestrictedDispatchDeadlockClient1 : public Worker {
1418 public:
1419 RestrictedDispatchDeadlockClient1(RestrictedDispatchDeadlockServer* server,
1420 RestrictedDispatchDeadlockClient2* peer,
1421 WaitableEvent* server_ready_event,
1422 WaitableEvent** events)
1423 : Worker("channel1", Channel::MODE_CLIENT),
1424 server_(server),
1425 peer_(peer),
1426 server_ready_event_(server_ready_event),
1427 events_(events),
1428 received_msg_(false),
1429 received_noarg_reply_(false),
1430 done_issued_(false) {}
1431
dchengfe61fca2014-10-22 02:29:521432 void Run() override {
[email protected]522cc10d2012-01-11 22:39:541433 server_ready_event_->Wait();
skyostile687bdff2015-05-12 11:29:211434 server_->ListenerThread()->task_runner()->PostTask(
[email protected]522cc10d2012-01-11 22:39:541435 FROM_HERE,
1436 base::Bind(&RestrictedDispatchDeadlockServer::OnDoServerTask, server_));
skyostile687bdff2015-05-12 11:29:211437 peer_->ListenerThread()->task_runner()->PostTask(
[email protected]522cc10d2012-01-11 22:39:541438 FROM_HERE,
1439 base::Bind(&RestrictedDispatchDeadlockClient2::OnDoClient2Task, peer_));
1440 events_[0]->Wait();
1441 events_[1]->Wait();
1442 DCHECK(received_msg_ == false);
1443
1444 Message* message = new SyncChannelTestMsg_NoArgs;
1445 message->set_unblock(true);
1446 Send(message);
1447 received_noarg_reply_ = true;
1448 PossiblyDone();
1449 }
1450
[email protected]522cc10d2012-01-11 22:39:541451 private:
dchengfe61fca2014-10-22 02:29:521452 bool OnMessageReceived(const Message& message) override {
[email protected]522cc10d2012-01-11 22:39:541453 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchDeadlockClient1, message)
1454 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs)
1455 IPC_END_MESSAGE_MAP()
1456 return true;
1457 }
1458
1459 void OnNoArgs() {
1460 received_msg_ = true;
1461 PossiblyDone();
1462 }
1463
1464 void PossiblyDone() {
1465 if (received_noarg_reply_ && received_msg_) {
1466 DCHECK(done_issued_ == false);
1467 done_issued_ = true;
1468 Send(new SyncChannelTestMsg_Done);
1469 Done();
1470 }
1471 }
1472
1473 RestrictedDispatchDeadlockServer* server_;
1474 RestrictedDispatchDeadlockClient2* peer_;
1475 WaitableEvent* server_ready_event_;
1476 WaitableEvent** events_;
1477 bool received_msg_;
1478 bool received_noarg_reply_;
1479 bool done_issued_;
1480};
1481
[email protected]522cc10d2012-01-11 22:39:541482TEST_F(IPCSyncChannelTest, RestrictedDispatchDeadlock) {
1483 std::vector<Worker*> workers;
1484
1485 // A shared worker thread so that server1 and server2 run on one thread.
1486 base::Thread worker_thread("RestrictedDispatchDeadlock");
1487 ASSERT_TRUE(worker_thread.Start());
1488
1489 WaitableEvent server1_ready(false, false);
1490 WaitableEvent server2_ready(false, false);
1491
1492 WaitableEvent event0(false, false);
1493 WaitableEvent event1(false, false);
1494 WaitableEvent event2(false, false);
1495 WaitableEvent event3(false, false);
1496 WaitableEvent* events[4] = {&event0, &event1, &event2, &event3};
1497
1498 RestrictedDispatchDeadlockServer* server1;
1499 RestrictedDispatchDeadlockServer* server2;
1500 RestrictedDispatchDeadlockClient1* client1;
1501 RestrictedDispatchDeadlockClient2* client2;
1502
1503 server2 = new RestrictedDispatchDeadlockServer(2, &server2_ready, events,
1504 NULL);
1505 server2->OverrideThread(&worker_thread);
1506 workers.push_back(server2);
1507
1508 client2 = new RestrictedDispatchDeadlockClient2(server2, &server2_ready,
1509 events);
1510 workers.push_back(client2);
1511
1512 server1 = new RestrictedDispatchDeadlockServer(1, &server1_ready, events,
1513 server2);
1514 server1->OverrideThread(&worker_thread);
1515 workers.push_back(server1);
1516
1517 client1 = new RestrictedDispatchDeadlockClient1(server1, client2,
1518 &server1_ready, events);
1519 workers.push_back(client1);
1520
1521 RunTest(workers);
1522}
1523
[email protected]2a3aa7b52013-01-11 20:56:221524//------------------------------------------------------------------------------
[email protected]5c41e6e12012-03-17 02:20:461525
[email protected]298ee7d2012-03-30 21:29:301526// This test case inspired by crbug.com/120530
1527// We create 4 workers that pipe to each other W1->W2->W3->W4->W1 then we send a
1528// message that recurses through 3, 4 or 5 steps to make sure, say, W1 can
1529// re-enter when called from W4 while it's sending a message to W2.
1530// The first worker drives the whole test so it must be treated specially.
[email protected]298ee7d2012-03-30 21:29:301531
1532class RestrictedDispatchPipeWorker : public Worker {
1533 public:
1534 RestrictedDispatchPipeWorker(
1535 const std::string &channel1,
1536 WaitableEvent* event1,
1537 const std::string &channel2,
1538 WaitableEvent* event2,
1539 int group,
1540 int* success)
1541 : Worker(channel1, Channel::MODE_SERVER),
1542 event1_(event1),
1543 event2_(event2),
1544 other_channel_name_(channel2),
1545 group_(group),
1546 success_(success) {
1547 }
1548
1549 void OnPingTTL(int ping, int* ret) {
1550 *ret = 0;
1551 if (!ping)
1552 return;
1553 other_channel_->Send(new SyncChannelTestMsg_PingTTL(ping - 1, ret));
1554 ++*ret;
1555 }
1556
1557 void OnDone() {
1558 if (is_first())
1559 return;
1560 other_channel_->Send(new SyncChannelTestMsg_Done);
1561 other_channel_.reset();
1562 Done();
1563 }
1564
dchengfe61fca2014-10-22 02:29:521565 void Run() override {
[email protected]298ee7d2012-03-30 21:29:301566 channel()->SetRestrictDispatchChannelGroup(group_);
1567 if (is_first())
1568 event1_->Signal();
1569 event2_->Wait();
skyostile687bdff2015-05-12 11:29:211570 other_channel_ = SyncChannel::Create(
1571 other_channel_name_, IPC::Channel::MODE_CLIENT, this,
erikchen30dc2812015-09-24 03:26:381572 ipc_thread().task_runner().get(), true, shutdown_event());
[email protected]298ee7d2012-03-30 21:29:301573 other_channel_->SetRestrictDispatchChannelGroup(group_);
1574 if (!is_first()) {
1575 event1_->Signal();
1576 return;
1577 }
1578 *success_ = 0;
1579 int value = 0;
1580 OnPingTTL(3, &value);
1581 *success_ += (value == 3);
1582 OnPingTTL(4, &value);
1583 *success_ += (value == 4);
1584 OnPingTTL(5, &value);
1585 *success_ += (value == 5);
1586 other_channel_->Send(new SyncChannelTestMsg_Done);
1587 other_channel_.reset();
1588 Done();
1589 }
1590
1591 bool is_first() { return !!success_; }
1592
1593 private:
dchengfe61fca2014-10-22 02:29:521594 bool OnMessageReceived(const Message& message) override {
[email protected]298ee7d2012-03-30 21:29:301595 IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchPipeWorker, message)
1596 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_PingTTL, OnPingTTL)
1597 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, OnDone)
1598 IPC_END_MESSAGE_MAP()
1599 return true;
1600 }
1601
1602 scoped_ptr<SyncChannel> other_channel_;
1603 WaitableEvent* event1_;
1604 WaitableEvent* event2_;
1605 std::string other_channel_name_;
1606 int group_;
1607 int* success_;
1608};
1609
tfarina8514f0d2015-07-28 14:41:471610#if defined(OS_ANDROID)
1611#define MAYBE_RestrictedDispatch4WayDeadlock \
1612 DISABLED_RestrictedDispatch4WayDeadlock
1613#else
1614#define MAYBE_RestrictedDispatch4WayDeadlock RestrictedDispatch4WayDeadlock
1615#endif
1616TEST_F(IPCSyncChannelTest, MAYBE_RestrictedDispatch4WayDeadlock) {
[email protected]298ee7d2012-03-30 21:29:301617 int success = 0;
1618 std::vector<Worker*> workers;
1619 WaitableEvent event0(true, false);
1620 WaitableEvent event1(true, false);
1621 WaitableEvent event2(true, false);
1622 WaitableEvent event3(true, false);
1623 workers.push_back(new RestrictedDispatchPipeWorker(
1624 "channel0", &event0, "channel1", &event1, 1, &success));
1625 workers.push_back(new RestrictedDispatchPipeWorker(
1626 "channel1", &event1, "channel2", &event2, 2, NULL));
1627 workers.push_back(new RestrictedDispatchPipeWorker(
1628 "channel2", &event2, "channel3", &event3, 3, NULL));
1629 workers.push_back(new RestrictedDispatchPipeWorker(
1630 "channel3", &event3, "channel0", &event0, 4, NULL));
1631 RunTest(workers);
1632 EXPECT_EQ(3, success);
1633}
1634
[email protected]2a3aa7b52013-01-11 20:56:221635//------------------------------------------------------------------------------
[email protected]9134cce6d2012-04-10 20:07:531636
[email protected]9134cce6d2012-04-10 20:07:531637// This test case inspired by crbug.com/122443
1638// We want to make sure a reply message with the unblock flag set correctly
1639// behaves as a reply, not a regular message.
1640// We have 3 workers. Server1 will send a message to Server2 (which will block),
1641// during which it will dispatch a message comming from Client, at which point
1642// it will send another message to Server2. While sending that second message it
1643// will receive a reply from Server1 with the unblock flag.
1644
[email protected]9134cce6d2012-04-10 20:07:531645class ReentrantReplyServer1 : public Worker {
1646 public:
1647 ReentrantReplyServer1(WaitableEvent* server_ready)
1648 : Worker("reentrant_reply1", Channel::MODE_SERVER),
1649 server_ready_(server_ready) { }
1650
dchengfe61fca2014-10-22 02:29:521651 void Run() override {
skyostile687bdff2015-05-12 11:29:211652 server2_channel_ = SyncChannel::Create(
1653 "reentrant_reply2", IPC::Channel::MODE_CLIENT, this,
erikchen30dc2812015-09-24 03:26:381654 ipc_thread().task_runner().get(), true, shutdown_event());
[email protected]9134cce6d2012-04-10 20:07:531655 server_ready_->Signal();
1656 Message* msg = new SyncChannelTestMsg_Reentrant1();
1657 server2_channel_->Send(msg);
1658 server2_channel_.reset();
1659 Done();
1660 }
1661
1662 private:
dchengfe61fca2014-10-22 02:29:521663 bool OnMessageReceived(const Message& message) override {
[email protected]9134cce6d2012-04-10 20:07:531664 IPC_BEGIN_MESSAGE_MAP(ReentrantReplyServer1, message)
1665 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Reentrant2, OnReentrant2)
1666 IPC_REPLY_HANDLER(OnReply)
1667 IPC_END_MESSAGE_MAP()
1668 return true;
1669 }
1670
1671 void OnReentrant2() {
1672 Message* msg = new SyncChannelTestMsg_Reentrant3();
1673 server2_channel_->Send(msg);
1674 }
1675
1676 void OnReply(const Message& message) {
1677 // If we get here, the Send() will never receive the reply (thus would
1678 // hang), so abort instead.
1679 LOG(FATAL) << "Reply message was dispatched";
1680 }
1681
1682 WaitableEvent* server_ready_;
1683 scoped_ptr<SyncChannel> server2_channel_;
1684};
1685
1686class ReentrantReplyServer2 : public Worker {
1687 public:
1688 ReentrantReplyServer2()
1689 : Worker("reentrant_reply2", Channel::MODE_SERVER),
1690 reply_(NULL) { }
1691
1692 private:
dchengfe61fca2014-10-22 02:29:521693 bool OnMessageReceived(const Message& message) override {
[email protected]9134cce6d2012-04-10 20:07:531694 IPC_BEGIN_MESSAGE_MAP(ReentrantReplyServer2, message)
1695 IPC_MESSAGE_HANDLER_DELAY_REPLY(
1696 SyncChannelTestMsg_Reentrant1, OnReentrant1)
1697 IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Reentrant3, OnReentrant3)
1698 IPC_END_MESSAGE_MAP()
1699 return true;
1700 }
1701
1702 void OnReentrant1(Message* reply) {
1703 DCHECK(!reply_);
1704 reply_ = reply;
1705 }
1706
1707 void OnReentrant3() {
1708 DCHECK(reply_);
1709 Message* reply = reply_;
1710 reply_ = NULL;
1711 reply->set_unblock(true);
1712 Send(reply);
1713 Done();
1714 }
1715
1716 Message* reply_;
1717};
1718
1719class ReentrantReplyClient : public Worker {
1720 public:
1721 ReentrantReplyClient(WaitableEvent* server_ready)
1722 : Worker("reentrant_reply1", Channel::MODE_CLIENT),
1723 server_ready_(server_ready) { }
1724
dchengfe61fca2014-10-22 02:29:521725 void Run() override {
[email protected]9134cce6d2012-04-10 20:07:531726 server_ready_->Wait();
1727 Send(new SyncChannelTestMsg_Reentrant2());
1728 Done();
1729 }
1730
1731 private:
1732 WaitableEvent* server_ready_;
1733};
1734
[email protected]9134cce6d2012-04-10 20:07:531735TEST_F(IPCSyncChannelTest, ReentrantReply) {
1736 std::vector<Worker*> workers;
1737 WaitableEvent server_ready(false, false);
1738 workers.push_back(new ReentrantReplyServer2());
1739 workers.push_back(new ReentrantReplyServer1(&server_ready));
1740 workers.push_back(new ReentrantReplyClient(&server_ready));
1741 RunTest(workers);
1742}
1743
[email protected]2a3aa7b52013-01-11 20:56:221744//------------------------------------------------------------------------------
[email protected]298ee7d2012-03-30 21:29:301745
[email protected]5c41e6e12012-03-17 02:20:461746// Generate a validated channel ID using Channel::GenerateVerifiedChannelID().
[email protected]5c41e6e12012-03-17 02:20:461747
1748class VerifiedServer : public Worker {
1749 public:
1750 VerifiedServer(base::Thread* listener_thread,
1751 const std::string& channel_name,
1752 const std::string& reply_text)
1753 : Worker(channel_name, Channel::MODE_SERVER),
1754 reply_text_(reply_text) {
1755 Worker::OverrideThread(listener_thread);
1756 }
1757
dchengfe61fca2014-10-22 02:29:521758 void OnNestedTestMsg(Message* reply_msg) override {
[email protected]5c41e6e12012-03-17 02:20:461759 VLOG(1) << __FUNCTION__ << " Sending reply: " << reply_text_;
1760 SyncChannelNestedTestMsg_String::WriteReplyParams(reply_msg, reply_text_);
1761 Send(reply_msg);
perkjdbcac352014-12-11 17:27:581762 ASSERT_EQ(channel()->GetPeerPID(), base::GetCurrentProcId());
[email protected]5c41e6e12012-03-17 02:20:461763 Done();
1764 }
1765
1766 private:
1767 std::string reply_text_;
1768};
1769
1770class VerifiedClient : public Worker {
1771 public:
1772 VerifiedClient(base::Thread* listener_thread,
1773 const std::string& channel_name,
1774 const std::string& expected_text)
1775 : Worker(channel_name, Channel::MODE_CLIENT),
1776 expected_text_(expected_text) {
1777 Worker::OverrideThread(listener_thread);
1778 }
1779
dchengfe61fca2014-10-22 02:29:521780 void Run() override {
[email protected]5c41e6e12012-03-17 02:20:461781 std::string response;
1782 SyncMessage* msg = new SyncChannelNestedTestMsg_String(&response);
1783 bool result = Send(msg);
1784 DCHECK(result);
1785 DCHECK_EQ(response, expected_text_);
[email protected]281bc5b2012-06-27 16:07:341786 // expected_text_ is only used in the above DCHECK. This line suppresses the
1787 // "unused private field" warning in release builds.
1788 (void)expected_text_;
[email protected]5c41e6e12012-03-17 02:20:461789
1790 VLOG(1) << __FUNCTION__ << " Received reply: " << response;
perkjdbcac352014-12-11 17:27:581791 ASSERT_EQ(channel()->GetPeerPID(), base::GetCurrentProcId());
[email protected]5c41e6e12012-03-17 02:20:461792 Done();
1793 }
1794
1795 private:
[email protected]5c41e6e12012-03-17 02:20:461796 std::string expected_text_;
1797};
1798
1799void Verified() {
1800 std::vector<Worker*> workers;
1801
1802 // A shared worker thread for servers
1803 base::Thread server_worker_thread("Verified_ServerListener");
1804 ASSERT_TRUE(server_worker_thread.Start());
1805
1806 base::Thread client_worker_thread("Verified_ClientListener");
1807 ASSERT_TRUE(client_worker_thread.Start());
1808
1809 std::string channel_id = Channel::GenerateVerifiedChannelID("Verified");
1810 Worker* worker;
1811
1812 worker = new VerifiedServer(&server_worker_thread,
1813 channel_id,
1814 "Got first message");
1815 workers.push_back(worker);
1816
1817 worker = new VerifiedClient(&client_worker_thread,
1818 channel_id,
1819 "Got first message");
1820 workers.push_back(worker);
1821
1822 RunTest(workers);
[email protected]5c41e6e12012-03-17 02:20:461823}
1824
[email protected]5c41e6e12012-03-17 02:20:461825// Windows needs to send an out-of-band secret to verify the client end of the
1826// channel. Test that we still connect correctly in that case.
1827TEST_F(IPCSyncChannelTest, Verified) {
1828 Verified();
1829}
1830
[email protected]2a3aa7b52013-01-11 20:56:221831} // namespace
[email protected]2d6e6a72013-02-08 20:11:021832} // namespace IPC