OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |