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

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

Issue 18324: POSIX: Get IPCSyncChannel unittests working (Closed)
Patch Set: Addressing comments Created 11 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // Unit test for SyncChannel. 5 // Unit test for SyncChannel.
6 6
7 #include <windows.h>
8 #include <string> 7 #include <string>
9 #include <vector> 8 #include <vector>
10 9
11 #include "base/basictypes.h" 10 #include "base/basictypes.h"
12 #include "base/logging.h" 11 #include "base/logging.h"
13 #include "base/message_loop.h" 12 #include "base/message_loop.h"
13 #include "base/platform_thread.h"
14 #include "base/string_util.h" 14 #include "base/string_util.h"
15 #include "base/thread.h" 15 #include "base/thread.h"
16 #include "base/waitable_event.h"
16 #include "chrome/common/child_process.h" 17 #include "chrome/common/child_process.h"
17 #include "chrome/common/ipc_message.h" 18 #include "chrome/common/ipc_message.h"
18 #include "chrome/common/ipc_sync_channel.h" 19 #include "chrome/common/ipc_sync_channel.h"
19 #include "chrome/common/stl_util-inl.h" 20 #include "chrome/common/stl_util-inl.h"
20 #include "testing/gtest/include/gtest/gtest.h" 21 #include "testing/gtest/include/gtest/gtest.h"
21 22
22 #define IPC_MESSAGE_MACROS_ENUMS 23 #define IPC_MESSAGE_MACROS_ENUMS
23 #include "chrome/common/ipc_sync_channel_unittest.h" 24 #include "chrome/common/ipc_sync_channel_unittest.h"
24 25
25 // define the classes 26 // define the classes
26 #define IPC_MESSAGE_MACROS_CLASSES 27 #define IPC_MESSAGE_MACROS_CLASSES
27 #include "chrome/common/ipc_sync_channel_unittest.h" 28 #include "chrome/common/ipc_sync_channel_unittest.h"
28 29
29 using namespace IPC; 30 using namespace IPC;
31 using base::WaitableEvent;
30 32
31 namespace { 33 namespace {
32 34
33 class IPCSyncChannelTest : public testing::Test { 35 class IPCSyncChannelTest : public testing::Test {
34 private: 36 private:
35 MessageLoop message_loop_; 37 MessageLoop message_loop_;
36 }; 38 };
37 39
38 // SyncChannel should only be used in child processes as we don't want to hang 40 // SyncChannel should only be used in child processes as we don't want to hang
39 // the browser. So in the unit test we need to have a ChildProcess object. 41 // the browser. So in the unit test we need to have a ChildProcess object.
40 class TestProcess : public ChildProcess { 42 class TestProcess : public ChildProcess {
41 public: 43 public:
42 explicit TestProcess(const std::wstring& channel_name) {} 44 explicit TestProcess(const std::wstring& channel_name) {}
43 static void GlobalInit() { 45 static void GlobalInit() {
44 ChildProcessFactory<TestProcess> factory; 46 ChildProcessFactory<TestProcess> factory;
45 ChildProcess::GlobalInit(L"blah", &factory); 47 ChildProcess::GlobalInit(L"blah", &factory);
46 } 48 }
47 }; 49 };
48 50
49 // Wrapper around an event handle.
50 class Event {
51 public:
52 Event() : handle_(CreateEvent(NULL, FALSE, FALSE, NULL)) { }
53 ~Event() { CloseHandle(handle_); }
54 void Set() { SetEvent(handle_); }
55 void Wait() { WaitForSingleObject(handle_, INFINITE); }
56 HANDLE handle() { return handle_; }
57
58 private:
59 HANDLE handle_;
60
61 DISALLOW_EVIL_CONSTRUCTORS(Event);
62 };
63
64 // Base class for a "process" with listener and IPC threads. 51 // Base class for a "process" with listener and IPC threads.
65 class Worker : public Channel::Listener, public Message::Sender { 52 class Worker : public Channel::Listener, public Message::Sender {
66 public: 53 public:
67 // Will create a channel without a name. 54 // Will create a channel without a name.
68 Worker(Channel::Mode mode, const std::string& thread_name) 55 Worker(Channel::Mode mode, const std::string& thread_name)
69 : channel_name_(), 56 : done_(new WaitableEvent(false, false)),
57 channel_created_(new WaitableEvent(false, false)),
70 mode_(mode), 58 mode_(mode),
71 ipc_thread_((thread_name + "_ipc").c_str()), 59 ipc_thread_((thread_name + "_ipc").c_str()),
72 listener_thread_((thread_name + "_listener").c_str()), 60 listener_thread_((thread_name + "_listener").c_str()),
73 overrided_thread_(NULL) { } 61 overrided_thread_(NULL) { }
74 62
75 // Will create a named channel and use this name for the threads' name. 63 // Will create a named channel and use this name for the threads' name.
76 Worker(const std::wstring& channel_name, Channel::Mode mode) 64 Worker(const std::wstring& channel_name, Channel::Mode mode)
77 : channel_name_(channel_name), 65 : done_(new WaitableEvent(false, false)),
66 channel_created_(new WaitableEvent(false, false)),
67 channel_name_(channel_name),
78 mode_(mode), 68 mode_(mode),
79 ipc_thread_((WideToUTF8(channel_name) + "_ipc").c_str()), 69 ipc_thread_((WideToUTF8(channel_name) + "_ipc").c_str()),
80 listener_thread_((WideToUTF8(channel_name) + "_listener").c_str()), 70 listener_thread_((WideToUTF8(channel_name) + "_listener").c_str()),
81 overrided_thread_(NULL) { } 71 overrided_thread_(NULL) { }
82 72
83 // The IPC thread needs to outlive SyncChannel, so force the correct order of 73 // The IPC thread needs to outlive SyncChannel, so force the correct order of
84 // destruction. 74 // destruction.
85 virtual ~Worker() { 75 virtual ~Worker() {
86 Event listener_done, ipc_done; 76 WaitableEvent listener_done(false, false), ipc_done(false, false);
87 ListenerThread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( 77 ListenerThread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
88 this, &Worker::OnListenerThreadShutdown, listener_done.handle(), 78 this, &Worker::OnListenerThreadShutdown, &listener_done,
89 ipc_done.handle())); 79 &ipc_done));
90 HANDLE handles[] = { listener_done.handle(), ipc_done.handle() }; 80 listener_done.Wait();
91 WaitForMultipleObjects(2, handles, TRUE, INFINITE); 81 ipc_done.Wait();
92 ipc_thread_.Stop(); 82 ipc_thread_.Stop();
93 listener_thread_.Stop(); 83 listener_thread_.Stop();
94 } 84 }
95 void AddRef() { } 85 void AddRef() { }
96 void Release() { } 86 void Release() { }
97 bool Send(Message* msg) { return channel_->Send(msg); } 87 bool Send(Message* msg) { return channel_->Send(msg); }
98 bool SendWithTimeout(Message* msg, int timeout_ms) { 88 bool SendWithTimeout(Message* msg, int timeout_ms) {
99 return channel_->SendWithTimeout(msg, timeout_ms); 89 return channel_->SendWithTimeout(msg, timeout_ms);
100 } 90 }
101 void WaitForChannelCreation() { channel_created_.Wait(); } 91 void WaitForChannelCreation() { channel_created_->Wait(); }
102 void CloseChannel() { 92 void CloseChannel() {
103 DCHECK(MessageLoop::current() == ListenerThread()->message_loop()); 93 DCHECK(MessageLoop::current() == ListenerThread()->message_loop());
104 channel_->Close(); 94 channel_->Close();
105 } 95 }
106 void Start() { 96 void Start() {
107 StartThread(&listener_thread_, MessageLoop::TYPE_DEFAULT); 97 StartThread(&listener_thread_, MessageLoop::TYPE_DEFAULT);
108 ListenerThread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod( 98 ListenerThread()->message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
109 this, &Worker::OnStart)); 99 this, &Worker::OnStart));
110 } 100 }
111 void OverrideThread(base::Thread* overrided_thread) { 101 void OverrideThread(base::Thread* overrided_thread) {
(...skipping 14 matching lines...) Expand all
126 int answer = 0; 116 int answer = 0;
127 SyncMessage* msg = new SyncChannelTestMsg_Double(5, &answer); 117 SyncMessage* msg = new SyncChannelTestMsg_Double(5, &answer);
128 if (pump) 118 if (pump)
129 msg->EnableMessagePumping(); 119 msg->EnableMessagePumping();
130 bool result = Send(msg); 120 bool result = Send(msg);
131 DCHECK(result == succeed); 121 DCHECK(result == succeed);
132 DCHECK(answer == (succeed ? 10 : 0)); 122 DCHECK(answer == (succeed ? 10 : 0));
133 return result; 123 return result;
134 } 124 }
135 Channel::Mode mode() { return mode_; } 125 Channel::Mode mode() { return mode_; }
136 HANDLE done_event() { return done_.handle(); } 126 WaitableEvent* done_event() { return done_.get(); }
137 127
138 protected: 128 protected:
139 // Derived classes need to call this when they've completed their part of 129 // Derived classes need to call this when they've completed their part of
140 // the test. 130 // the test.
141 void Done() { done_.Set(); } 131 void Done() { done_->Signal(); }
142 // Functions for dervied classes to implement if they wish. 132 // Functions for dervied classes to implement if they wish.
143 virtual void Run() { } 133 virtual void Run() { }
144 virtual void OnAnswer(int* answer) { NOTREACHED(); } 134 virtual void OnAnswer(int* answer) { NOTREACHED(); }
145 virtual void OnAnswerDelay(Message* reply_msg) { 135 virtual void OnAnswerDelay(Message* reply_msg) {
146 // The message handler map below can only take one entry for 136 // The message handler map below can only take one entry for
147 // SyncChannelTestMsg_AnswerToLife, so since some classes want 137 // SyncChannelTestMsg_AnswerToLife, so since some classes want
148 // the normal version while other want the delayed reply, we 138 // the normal version while other want the delayed reply, we
149 // call the normal version if the derived class didn't override 139 // call the normal version if the derived class didn't override
150 // this function. 140 // this function.
151 int answer; 141 int answer;
(...skipping 13 matching lines...) Expand all
165 base::Thread* ListenerThread() { 155 base::Thread* ListenerThread() {
166 return overrided_thread_ ? overrided_thread_ : &listener_thread_; 156 return overrided_thread_ ? overrided_thread_ : &listener_thread_;
167 } 157 }
168 // Called on the listener thread to create the sync channel. 158 // Called on the listener thread to create the sync channel.
169 void OnStart() { 159 void OnStart() {
170 // Link ipc_thread_, listener_thread_ and channel_ altogether. 160 // Link ipc_thread_, listener_thread_ and channel_ altogether.
171 StartThread(&ipc_thread_, MessageLoop::TYPE_IO); 161 StartThread(&ipc_thread_, MessageLoop::TYPE_IO);
172 channel_.reset(new SyncChannel( 162 channel_.reset(new SyncChannel(
173 channel_name_, mode_, this, NULL, ipc_thread_.message_loop(), true, 163 channel_name_, mode_, this, NULL, ipc_thread_.message_loop(), true,
174 TestProcess::GetShutDownEvent())); 164 TestProcess::GetShutDownEvent()));
175 channel_created_.Set(); 165 channel_created_->Signal();
176 Run(); 166 Run();
177 } 167 }
178 168
179 void OnListenerThreadShutdown(HANDLE listener_event, HANDLE ipc_event) { 169 void OnListenerThreadShutdown(WaitableEvent* listener_event,
170 WaitableEvent* ipc_event) {
180 // SyncChannel needs to be destructed on the thread that it was created on. 171 // SyncChannel needs to be destructed on the thread that it was created on.
181 channel_.reset(); 172 channel_.reset();
182 SetEvent(listener_event); 173 listener_event->Signal();
183 174
184 ipc_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod( 175 ipc_thread_.message_loop()->PostTask(FROM_HERE, NewRunnableMethod(
185 this, &Worker::OnIPCThreadShutdown, ipc_event)); 176 this, &Worker::OnIPCThreadShutdown, ipc_event));
186 } 177 }
187 178
188 void OnIPCThreadShutdown(HANDLE ipc_event) { 179 void OnIPCThreadShutdown(WaitableEvent* ipc_event) {
189 SetEvent(ipc_event); 180 ipc_event->Signal();
190 } 181 }
191 182
192 void OnMessageReceived(const Message& message) { 183 void OnMessageReceived(const Message& message) {
193 IPC_BEGIN_MESSAGE_MAP(Worker, message) 184 IPC_BEGIN_MESSAGE_MAP(Worker, message)
194 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_Double, OnDoubleDelay) 185 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_Double, OnDoubleDelay)
195 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_AnswerToLife, 186 IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_AnswerToLife,
196 OnAnswerDelay) 187 OnAnswerDelay)
197 IPC_END_MESSAGE_MAP() 188 IPC_END_MESSAGE_MAP()
198 } 189 }
199 190
200 void StartThread(base::Thread* thread, MessageLoop::Type type) { 191 void StartThread(base::Thread* thread, MessageLoop::Type type) {
201 base::Thread::Options options; 192 base::Thread::Options options;
202 options.message_loop_type = type; 193 options.message_loop_type = type;
203 thread->StartWithOptions(options); 194 thread->StartWithOptions(options);
204 } 195 }
205 196
206 Event done_; 197 scoped_ptr<WaitableEvent> done_;
207 Event channel_created_; 198 scoped_ptr<WaitableEvent> channel_created_;
208 std::wstring channel_name_; 199 std::wstring channel_name_;
209 Channel::Mode mode_; 200 Channel::Mode mode_;
210 scoped_ptr<SyncChannel> channel_; 201 scoped_ptr<SyncChannel> channel_;
211 base::Thread ipc_thread_; 202 base::Thread ipc_thread_;
212 base::Thread listener_thread_; 203 base::Thread listener_thread_;
213 base::Thread* overrided_thread_; 204 base::Thread* overrided_thread_;
214 205
215 DISALLOW_EVIL_CONSTRUCTORS(Worker); 206 DISALLOW_EVIL_CONSTRUCTORS(Worker);
216 }; 207 };
217 208
(...skipping 12 matching lines...) Expand all
230 } 221 }
231 } 222 }
232 223
233 // now create the clients 224 // now create the clients
234 for (size_t i = 0; i < workers.size(); ++i) { 225 for (size_t i = 0; i < workers.size(); ++i) {
235 if (workers[i]->mode() == Channel::MODE_CLIENT) 226 if (workers[i]->mode() == Channel::MODE_CLIENT)
236 workers[i]->Start(); 227 workers[i]->Start();
237 } 228 }
238 229
239 // wait for all the workers to finish 230 // wait for all the workers to finish
240 std::vector<HANDLE> done_handles;
241 for (size_t i = 0; i < workers.size(); ++i) 231 for (size_t i = 0; i < workers.size(); ++i)
242 done_handles.push_back(workers[i]->done_event()); 232 workers[i]->done_event()->Wait();
243 233
244 int count = static_cast<int>(done_handles.size());
245 WaitForMultipleObjects(count, &done_handles.front(), TRUE, INFINITE);
246 STLDeleteContainerPointers(workers.begin(), workers.end()); 234 STLDeleteContainerPointers(workers.begin(), workers.end());
247 235
248 TestProcess::GlobalCleanup(); 236 TestProcess::GlobalCleanup();
249 } 237 }
250 238
251 } // namespace 239 } // namespace
252 240
253 //----------------------------------------------------------------------------- 241 //-----------------------------------------------------------------------------
254 242
255 namespace { 243 namespace {
256 244
257 class SimpleServer : public Worker { 245 class SimpleServer : public Worker {
258 public: 246 public:
259 SimpleServer(bool pump_during_send) 247 SimpleServer(bool pump_during_send)
260 : Worker(Channel::MODE_SERVER, "simpler_server"), 248 : Worker(Channel::MODE_SERVER, "simpler_server"),
261 pump_during_send_(pump_during_send) { } 249 pump_during_send_(pump_during_send) { }
262 void Run() { 250 void Run() {
263 SendAnswerToLife(pump_during_send_, INFINITE, true); 251 SendAnswerToLife(pump_during_send_, base::kNoTimeout, true);
264 Done(); 252 Done();
265 } 253 }
266 254
267 bool pump_during_send_; 255 bool pump_during_send_;
268 }; 256 };
269 257
270 class SimpleClient : public Worker { 258 class SimpleClient : public Worker {
271 public: 259 public:
272 SimpleClient() : Worker(Channel::MODE_CLIENT, "simple_client") { } 260 SimpleClient() : Worker(Channel::MODE_CLIENT, "simple_client") { }
273 261
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
321 DelayReply(false); 309 DelayReply(false);
322 DelayReply(true); 310 DelayReply(true);
323 } 311 }
324 312
325 //----------------------------------------------------------------------------- 313 //-----------------------------------------------------------------------------
326 314
327 namespace { 315 namespace {
328 316
329 class NoHangServer : public Worker { 317 class NoHangServer : public Worker {
330 public: 318 public:
331 explicit NoHangServer(Event* got_first_reply, bool pump_during_send) 319 explicit NoHangServer(WaitableEvent* got_first_reply, bool pump_during_send)
332 : Worker(Channel::MODE_SERVER, "no_hang_server"), 320 : Worker(Channel::MODE_SERVER, "no_hang_server"),
333 got_first_reply_(got_first_reply), 321 got_first_reply_(got_first_reply),
334 pump_during_send_(pump_during_send) { } 322 pump_during_send_(pump_during_send) { }
335 void Run() { 323 void Run() {
336 SendAnswerToLife(pump_during_send_, INFINITE, true); 324 SendAnswerToLife(pump_during_send_, base::kNoTimeout, true);
337 got_first_reply_->Set(); 325 got_first_reply_->Signal();
338 326
339 SendAnswerToLife(pump_during_send_, INFINITE, false); 327 SendAnswerToLife(pump_during_send_, base::kNoTimeout, false);
340 Done(); 328 Done();
341 } 329 }
342 330
343 Event* got_first_reply_; 331 WaitableEvent* got_first_reply_;
344 bool pump_during_send_; 332 bool pump_during_send_;
345 }; 333 };
346 334
347 class NoHangClient : public Worker { 335 class NoHangClient : public Worker {
348 public: 336 public:
349 explicit NoHangClient(Event* got_first_reply) 337 explicit NoHangClient(WaitableEvent* got_first_reply)
350 : Worker(Channel::MODE_CLIENT, "no_hang_client"), 338 : Worker(Channel::MODE_CLIENT, "no_hang_client"),
351 got_first_reply_(got_first_reply) { } 339 got_first_reply_(got_first_reply) { }
352 340
353 virtual void OnAnswerDelay(Message* reply_msg) { 341 virtual void OnAnswerDelay(Message* reply_msg) {
354 // Use the DELAY_REPLY macro so that we can force the reply to be sent 342 // Use the DELAY_REPLY macro so that we can force the reply to be sent
355 // before this function returns (when the channel will be reset). 343 // before this function returns (when the channel will be reset).
356 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42); 344 SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42);
357 Send(reply_msg); 345 Send(reply_msg);
358 got_first_reply_->Wait(); 346 got_first_reply_->Wait();
359 CloseChannel(); 347 CloseChannel();
360 Done(); 348 Done();
361 } 349 }
362 350
363 Event* got_first_reply_; 351 WaitableEvent* got_first_reply_;
364 }; 352 };
365 353
366 void NoHang(bool pump_during_send) { 354 void NoHang(bool pump_during_send) {
367 Event got_first_reply; 355 WaitableEvent got_first_reply(false, false);
368 std::vector<Worker*> workers; 356 std::vector<Worker*> workers;
369 workers.push_back(new NoHangServer(&got_first_reply, pump_during_send)); 357 workers.push_back(new NoHangServer(&got_first_reply, pump_during_send));
370 workers.push_back(new NoHangClient(&got_first_reply)); 358 workers.push_back(new NoHangClient(&got_first_reply));
371 RunTest(workers); 359 RunTest(workers);
372 } 360 }
373 361
374 } // namespace 362 } // namespace
375 363
376 // Tests that caller doesn't hang if receiver dies 364 // Tests that caller doesn't hang if receiver dies
377 TEST_F(IPCSyncChannelTest, NoHang) { 365 TEST_F(IPCSyncChannelTest, NoHang) {
378 NoHang(false); 366 NoHang(false);
379 NoHang(true); 367 NoHang(true);
380 } 368 }
381 369
382 //----------------------------------------------------------------------------- 370 //-----------------------------------------------------------------------------
383 371
384 namespace { 372 namespace {
385 373
386 class UnblockServer : public Worker { 374 class UnblockServer : public Worker {
387 public: 375 public:
388 UnblockServer(bool pump_during_send) 376 UnblockServer(bool pump_during_send)
389 : Worker(Channel::MODE_SERVER, "unblock_server"), 377 : Worker(Channel::MODE_SERVER, "unblock_server"),
390 pump_during_send_(pump_during_send) { } 378 pump_during_send_(pump_during_send) { }
391 void Run() { 379 void Run() {
392 SendAnswerToLife(pump_during_send_, INFINITE, true); 380 SendAnswerToLife(pump_during_send_, base::kNoTimeout, true);
393 Done(); 381 Done();
394 } 382 }
395 383
396 void OnDouble(int in, int* out) { 384 void OnDouble(int in, int* out) {
397 *out = in * 2; 385 *out = in * 2;
398 } 386 }
399 387
400 bool pump_during_send_; 388 bool pump_during_send_;
401 }; 389 };
402 390
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
443 : Worker(Channel::MODE_SERVER, "recursive_server"), 431 : Worker(Channel::MODE_SERVER, "recursive_server"),
444 expected_send_result_(expected_send_result), 432 expected_send_result_(expected_send_result),
445 pump_first_(pump_first), pump_second_(pump_second) { } 433 pump_first_(pump_first), pump_second_(pump_second) { }
446 void Run() { 434 void Run() {
447 SendDouble(pump_first_, expected_send_result_); 435 SendDouble(pump_first_, expected_send_result_);
448 Done(); 436 Done();
449 } 437 }
450 438
451 void OnDouble(int in, int* out) { 439 void OnDouble(int in, int* out) {
452 *out = in * 2; 440 *out = in * 2;
453 SendAnswerToLife(pump_second_, INFINITE, expected_send_result_); 441 SendAnswerToLife(pump_second_, base::kNoTimeout, expected_send_result_);
454 } 442 }
455 443
456 bool expected_send_result_, pump_first_, pump_second_; 444 bool expected_send_result_, pump_first_, pump_second_;
457 }; 445 };
458 446
459 class RecursiveClient : public Worker { 447 class RecursiveClient : public Worker {
460 public: 448 public:
461 explicit RecursiveClient(bool pump_during_send, bool close_channel) 449 explicit RecursiveClient(bool pump_during_send, bool close_channel)
462 : Worker(Channel::MODE_CLIENT, "recursive_client"), 450 : Worker(Channel::MODE_CLIENT, "recursive_client"),
463 pump_during_send_(pump_during_send), close_channel_(close_channel) { } 451 pump_during_send_(pump_during_send), close_channel_(close_channel) { }
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 void Run() { 538 void Run() {
551 SendDouble(pump_during_send_, true); 539 SendDouble(pump_during_send_, true);
552 Done(); 540 Done();
553 } 541 }
554 542
555 bool pump_during_send_; 543 bool pump_during_send_;
556 }; 544 };
557 545
558 class MultipleClient1 : public Worker { 546 class MultipleClient1 : public Worker {
559 public: 547 public:
560 MultipleClient1(Event* client1_msg_received, Event* client1_can_reply) : 548 MultipleClient1(WaitableEvent* client1_msg_received,
549 WaitableEvent* client1_can_reply) :
561 Worker(L"test_channel1", Channel::MODE_CLIENT), 550 Worker(L"test_channel1", Channel::MODE_CLIENT),
562 client1_msg_received_(client1_msg_received), 551 client1_msg_received_(client1_msg_received),
563 client1_can_reply_(client1_can_reply) { } 552 client1_can_reply_(client1_can_reply) { }
564 553
565 void OnDouble(int in, int* out) { 554 void OnDouble(int in, int* out) {
566 client1_msg_received_->Set(); 555 client1_msg_received_->Signal();
567 *out = in * 2; 556 *out = in * 2;
568 client1_can_reply_->Wait(); 557 client1_can_reply_->Wait();
569 Done(); 558 Done();
570 } 559 }
571 560
572 private: 561 private:
573 Event *client1_msg_received_, *client1_can_reply_; 562 WaitableEvent *client1_msg_received_, *client1_can_reply_;
574 }; 563 };
575 564
576 class MultipleServer2 : public Worker { 565 class MultipleServer2 : public Worker {
577 public: 566 public:
578 MultipleServer2() : Worker(L"test_channel2", Channel::MODE_SERVER) { } 567 MultipleServer2() : Worker(L"test_channel2", Channel::MODE_SERVER) { }
579 568
580 void OnAnswer(int* result) { 569 void OnAnswer(int* result) {
581 *result = 42; 570 *result = 42;
582 Done(); 571 Done();
583 } 572 }
584 }; 573 };
585 574
586 class MultipleClient2 : public Worker { 575 class MultipleClient2 : public Worker {
587 public: 576 public:
588 MultipleClient2( 577 MultipleClient2(
589 Event* client1_msg_received, Event* client1_can_reply, 578 WaitableEvent* client1_msg_received, WaitableEvent* client1_can_reply,
590 bool pump_during_send) 579 bool pump_during_send)
591 : Worker(L"test_channel2", Channel::MODE_CLIENT), 580 : Worker(L"test_channel2", Channel::MODE_CLIENT),
592 client1_msg_received_(client1_msg_received), 581 client1_msg_received_(client1_msg_received),
593 client1_can_reply_(client1_can_reply), 582 client1_can_reply_(client1_can_reply),
594 pump_during_send_(pump_during_send) { } 583 pump_during_send_(pump_during_send) { }
595 584
596 void Run() { 585 void Run() {
597 client1_msg_received_->Wait(); 586 client1_msg_received_->Wait();
598 SendAnswerToLife(pump_during_send_, INFINITE, true); 587 SendAnswerToLife(pump_during_send_, base::kNoTimeout, true);
599 client1_can_reply_->Set(); 588 client1_can_reply_->Signal();
600 Done(); 589 Done();
601 } 590 }
602 591
603 private: 592 private:
604 Event *client1_msg_received_, *client1_can_reply_; 593 WaitableEvent *client1_msg_received_, *client1_can_reply_;
605 bool pump_during_send_; 594 bool pump_during_send_;
606 }; 595 };
607 596
608 void Multiple(bool server_pump, bool client_pump) { 597 void Multiple(bool server_pump, bool client_pump) {
609 std::vector<Worker*> workers; 598 std::vector<Worker*> workers;
610 599
611 // A shared worker thread so that server1 and server2 run on one thread. 600 // A shared worker thread so that server1 and server2 run on one thread.
612 base::Thread worker_thread("Multiple"); 601 base::Thread worker_thread("Multiple");
613 worker_thread.Start(); 602 worker_thread.Start();
614 603
615 // Server1 sends a sync msg to client1, which blocks the reply until 604 // Server1 sends a sync msg to client1, which blocks the reply until
616 // server2 (which runs on the same worker thread as server1) responds 605 // server2 (which runs on the same worker thread as server1) responds
617 // to a sync msg from client2. 606 // to a sync msg from client2.
618 Event client1_msg_received, client1_can_reply; 607 WaitableEvent client1_msg_received(false, false);
608 WaitableEvent client1_can_reply(false, false);
619 609
620 Worker* worker; 610 Worker* worker;
621 611
622 worker = new MultipleServer2(); 612 worker = new MultipleServer2();
623 worker->OverrideThread(&worker_thread); 613 worker->OverrideThread(&worker_thread);
624 workers.push_back(worker); 614 workers.push_back(worker);
625 615
626 worker = new MultipleClient2( 616 worker = new MultipleClient2(
627 &client1_msg_received, &client1_can_reply, client_pump); 617 &client1_msg_received, &client1_can_reply, client_pump);
628 workers.push_back(worker); 618 workers.push_back(worker);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 void Run() { 651 void Run() {
662 SendDouble(pump_during_send_, true); 652 SendDouble(pump_during_send_, true);
663 Done(); 653 Done();
664 } 654 }
665 655
666 bool pump_during_send_; 656 bool pump_during_send_;
667 }; 657 };
668 658
669 class QueuedReplyClient1 : public Worker { 659 class QueuedReplyClient1 : public Worker {
670 public: 660 public:
671 QueuedReplyClient1(Event* client1_msg_received, Event* server2_can_reply) : 661 QueuedReplyClient1(WaitableEvent* client1_msg_received,
662 WaitableEvent* server2_can_reply) :
672 Worker(L"test_channel1", Channel::MODE_CLIENT), 663 Worker(L"test_channel1", Channel::MODE_CLIENT),
673 client1_msg_received_(client1_msg_received), 664 client1_msg_received_(client1_msg_received),
674 server2_can_reply_(server2_can_reply) { } 665 server2_can_reply_(server2_can_reply) { }
675 666
676 void OnDouble(int in, int* out) { 667 void OnDouble(int in, int* out) {
677 client1_msg_received_->Set(); 668 client1_msg_received_->Signal();
678 *out = in * 2; 669 *out = in * 2;
679 server2_can_reply_->Wait(); 670 server2_can_reply_->Wait();
680 Done(); 671 Done();
681 } 672 }
682 673
683 private: 674 private:
684 Event *client1_msg_received_, *server2_can_reply_; 675 WaitableEvent *client1_msg_received_, *server2_can_reply_;
685 }; 676 };
686 677
687 class QueuedReplyServer2 : public Worker { 678 class QueuedReplyServer2 : public Worker {
688 public: 679 public:
689 explicit QueuedReplyServer2(Event* server2_can_reply) : 680 explicit QueuedReplyServer2(WaitableEvent* server2_can_reply) :
690 Worker(L"test_channel2", Channel::MODE_SERVER), 681 Worker(L"test_channel2", Channel::MODE_SERVER),
691 server2_can_reply_(server2_can_reply) { } 682 server2_can_reply_(server2_can_reply) { }
692 683
693 void OnAnswer(int* result) { 684 void OnAnswer(int* result) {
694 server2_can_reply_->Set(); 685 server2_can_reply_->Signal();
695 686
696 // give client1's reply time to reach the server listener thread 687 // give client1's reply time to reach the server listener thread
697 Sleep(200); 688 PlatformThread::Sleep(200);
698 689
699 *result = 42; 690 *result = 42;
700 Done(); 691 Done();
701 } 692 }
702 693
703 Event *server2_can_reply_; 694 WaitableEvent *server2_can_reply_;
704 }; 695 };
705 696
706 class QueuedReplyClient2 : public Worker { 697 class QueuedReplyClient2 : public Worker {
707 public: 698 public:
708 explicit QueuedReplyClient2( 699 explicit QueuedReplyClient2(
709 Event* client1_msg_received, bool pump_during_send) 700 WaitableEvent* client1_msg_received, bool pump_during_send)
710 : Worker(L"test_channel2", Channel::MODE_CLIENT), 701 : Worker(L"test_channel2", Channel::MODE_CLIENT),
711 client1_msg_received_(client1_msg_received), 702 client1_msg_received_(client1_msg_received),
712 pump_during_send_(pump_during_send){ } 703 pump_during_send_(pump_during_send){ }
713 704
714 void Run() { 705 void Run() {
715 client1_msg_received_->Wait(); 706 client1_msg_received_->Wait();
716 SendAnswerToLife(pump_during_send_, INFINITE, true); 707 SendAnswerToLife(pump_during_send_, base::kNoTimeout, true);
717 Done(); 708 Done();
718 } 709 }
719 710
720 Event *client1_msg_received_; 711 WaitableEvent *client1_msg_received_;
721 bool pump_during_send_; 712 bool pump_during_send_;
722 }; 713 };
723 714
724 void QueuedReply(bool server_pump, bool client_pump) { 715 void QueuedReply(bool server_pump, bool client_pump) {
725 std::vector<Worker*> workers; 716 std::vector<Worker*> workers;
726 717
727 // A shared worker thread so that server1 and server2 run on one thread. 718 // A shared worker thread so that server1 and server2 run on one thread.
728 base::Thread worker_thread("QueuedReply"); 719 base::Thread worker_thread("QueuedReply");
729 worker_thread.Start(); 720 worker_thread.Start();
730 721
731 Event client1_msg_received, server2_can_reply; 722 WaitableEvent client1_msg_received(false, false);
723 WaitableEvent server2_can_reply(false, false);
732 724
733 Worker* worker; 725 Worker* worker;
734 726
735 worker = new QueuedReplyServer2(&server2_can_reply); 727 worker = new QueuedReplyServer2(&server2_can_reply);
736 worker->OverrideThread(&worker_thread); 728 worker->OverrideThread(&worker_thread);
737 workers.push_back(worker); 729 workers.push_back(worker);
738 730
739 worker = new QueuedReplyClient2(&client1_msg_received, client_pump); 731 worker = new QueuedReplyClient2(&client1_msg_received, client_pump);
740 workers.push_back(worker); 732 workers.push_back(worker);
741 733
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
967 959
968 //------------------------------------------------------------------------------ 960 //------------------------------------------------------------------------------
969 961
970 namespace { 962 namespace {
971 963
972 class NestedTask : public Task { 964 class NestedTask : public Task {
973 public: 965 public:
974 NestedTask(Worker* server) : server_(server) { } 966 NestedTask(Worker* server) : server_(server) { }
975 void Run() { 967 void Run() {
976 // Sleep a bit so that we wake up after the reply has been received. 968 // Sleep a bit so that we wake up after the reply has been received.
977 Sleep(250); 969 PlatformThread::Sleep(250);
978 server_->SendAnswerToLife(true, INFINITE, true); 970 server_->SendAnswerToLife(true, base::kNoTimeout, true);
979 } 971 }
980 972
981 Worker* server_; 973 Worker* server_;
982 }; 974 };
983 975
984 static bool timeout_occured = false; 976 static bool timeout_occured = false;
985 977
986 class TimeoutTask : public Task { 978 class TimeoutTask : public Task {
987 public: 979 public:
988 void Run() { 980 void Run() {
(...skipping 23 matching lines...) Expand all
1012 1004
1013 // Tests http://b/1474092 - that if after the done_event is set but before 1005 // Tests http://b/1474092 - that if after the done_event is set but before
1014 // OnObjectSignaled is called another message is sent out, then after its 1006 // OnObjectSignaled is called another message is sent out, then after its
1015 // reply comes back OnObjectSignaled will be called for the first message. 1007 // reply comes back OnObjectSignaled will be called for the first message.
1016 TEST_F(IPCSyncChannelTest, DoneEventRace) { 1008 TEST_F(IPCSyncChannelTest, DoneEventRace) {
1017 std::vector<Worker*> workers; 1009 std::vector<Worker*> workers;
1018 workers.push_back(new DoneEventRaceServer()); 1010 workers.push_back(new DoneEventRaceServer());
1019 workers.push_back(new SimpleClient()); 1011 workers.push_back(new SimpleClient());
1020 RunTest(workers); 1012 RunTest(workers);
1021 } 1013 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698