ipc_sync_channel_unittest.cc revision 9ab5563a3196760eb381d102cbb2bc0f7abc6a50
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sync_channel.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 149ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/process_util.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/run_loop.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 18868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/synchronization/waitable_event.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_listener.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_message.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sender.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sync_message_filter.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sync_message_unittest.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::WaitableEvent; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace IPC { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Base class for a "process" with listener and IPC threads. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Worker : public Listener, public Sender { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Will create a channel without a name. 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Worker(Channel::Mode mode, const std::string& thread_name) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : done_(new WaitableEvent(false, false)), 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_created_(new WaitableEvent(false, false)), 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mode_(mode), 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ipc_thread_((thread_name + "_ipc").c_str()), 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_thread_((thread_name + "_listener").c_str()), 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overrided_thread_(NULL), 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shutdown_event_(true, false), 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_shutdown_(false) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Will create a named channel and use this name for the threads' name. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Worker(const std::string& channel_name, Channel::Mode mode) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : done_(new WaitableEvent(false, false)), 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_created_(new WaitableEvent(false, false)), 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_name_(channel_name), 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mode_(mode), 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ipc_thread_((channel_name + "_ipc").c_str()), 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_thread_((channel_name + "_listener").c_str()), 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overrided_thread_(NULL), 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) shutdown_event_(true, false), 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_shutdown_(false) { 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~Worker() { 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Shutdown() must be called before destruction. 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(is_shutdown_); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddRef() { } 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Release() { } 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool Send(Message* msg) OVERRIDE { return channel_->Send(msg); } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool SendWithTimeout(Message* msg, int timeout_ms) { 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel_->SendWithTimeout(msg, timeout_ms); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WaitForChannelCreation() { channel_created_->Wait(); } 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CloseChannel() { 73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(base::MessageLoop::current() == ListenerThread()->message_loop()); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_->Close(); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Start() { 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StartThread(&listener_thread_, base::MessageLoop::TYPE_DEFAULT); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListenerThread()->message_loop()->PostTask( 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&Worker::OnStart, this)); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Shutdown() { 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The IPC thread needs to outlive SyncChannel. We can't do this in 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // ~Worker(), since that'll reset the vtable pointer (to Worker's), which 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // may result in a race conditions. See http://crbug.com/25841. 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) WaitableEvent listener_done(false, false), ipc_done(false, false); 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ListenerThread()->message_loop()->PostTask( 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(&Worker::OnListenerThreadShutdown1, this, 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &listener_done, &ipc_done)); 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) listener_done.Wait(); 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ipc_done.Wait(); 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ipc_thread_.Stop(); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) listener_thread_.Stop(); 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_shutdown_ = true; 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OverrideThread(base::Thread* overrided_thread) { 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(overrided_thread_ == NULL); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) overrided_thread_ = overrided_thread; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool SendAnswerToLife(bool pump, int timeout, bool succeed) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int answer = 0; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pump) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg->EnableMessagePumping(); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = SendWithTimeout(msg, timeout); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(result, succeed); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(answer, (succeed ? 42 : 0)); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool SendDouble(bool pump, bool succeed) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int answer = 0; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncMessage* msg = new SyncChannelTestMsg_Double(5, &answer); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pump) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg->EnableMessagePumping(); 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = Send(msg); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(result, succeed); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(answer, (succeed ? 10 : 0)); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& channel_name() { return channel_name_; } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Channel::Mode mode() { return mode_; } 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* done_event() { return done_.get(); } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* shutdown_event() { return &shutdown_event_; } 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ResetChannel() { channel_.reset(); } 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Derived classes need to call this when they've completed their part of 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the test. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Done() { done_->Signal(); } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncChannel* channel() { return channel_.get(); } 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Functions for dervied classes to implement if they wish. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Run() { } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnAnswer(int* answer) { NOTREACHED(); } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnAnswerDelay(Message* reply_msg) { 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The message handler map below can only take one entry for 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SyncChannelTestMsg_AnswerToLife, so since some classes want 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the normal version while other want the delayed reply, we 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // call the normal version if the derived class didn't override 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this function. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int answer; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnAnswer(&answer); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, answer); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_msg); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnDouble(int in, int* out) { NOTREACHED(); } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnDoubleDelay(int in, Message* reply_msg) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result; 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnDouble(in, &result); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, result); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_msg); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void OnNestedTestMsg(Message* reply_msg) { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual SyncChannel* CreateChannel() { 1577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) return new SyncChannel(channel_name_, 1587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) mode_, 1597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) this, 1607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ipc_thread_.message_loop_proxy().get(), 1617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) true, 1627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) &shutdown_event_); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread* ListenerThread() { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return overrided_thread_ ? overrided_thread_ : &listener_thread_; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Thread& ipc_thread() const { return ipc_thread_; } 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called on the listener thread to create the sync channel. 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnStart() { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Link ipc_thread_, listener_thread_ and channel_ altogether. 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) StartThread(&ipc_thread_, base::MessageLoop::TYPE_IO); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_.reset(CreateChannel()); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_created_->Signal(); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Run(); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnListenerThreadShutdown1(WaitableEvent* listener_event, 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* ipc_event) { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // SyncChannel needs to be destructed on the thread that it was created on. 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_.reset(); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ipc_thread_.message_loop()->PostTask( 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&Worker::OnIPCThreadShutdown, this, 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_event, ipc_event)); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnIPCThreadShutdown(WaitableEvent* listener_event, 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* ipc_event) { 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ipc_event->Signal(); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_thread_.message_loop()->PostTask( 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&Worker::OnListenerThreadShutdown2, this, 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_event)); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnListenerThreadShutdown2(WaitableEvent* listener_event) { 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::RunLoop().RunUntilIdle(); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_event->Signal(); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool OnMessageReceived(const Message& message) OVERRIDE { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(Worker, message) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_Double, OnDoubleDelay) 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_AnswerToLife, 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnAnswerDelay) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelNestedTestMsg_String, 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnNestedTestMsg) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) void StartThread(base::Thread* thread, base::MessageLoop::Type type) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread::Options options; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.message_loop_type = type; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread->StartWithOptions(options); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<WaitableEvent> done_; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<WaitableEvent> channel_created_; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string channel_name_; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Channel::Mode mode_; 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SyncChannel> channel_; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread ipc_thread_; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread listener_thread_; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread* overrided_thread_; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent shutdown_event_; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool is_shutdown_; 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Worker); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Starts the test with the given workers. This function deletes the workers 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// when it's done. 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RunTest(std::vector<Worker*> workers) { 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First we create the workers that are channel servers, or else the other 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // workers' channel initialization might fail because the pipe isn't created.. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < workers.size(); ++i) { 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (workers[i]->mode() & Channel::MODE_SERVER_FLAG) { 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers[i]->Start(); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers[i]->WaitForChannelCreation(); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // now create the clients 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < workers.size(); ++i) { 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (workers[i]->mode() & Channel::MODE_CLIENT_FLAG) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers[i]->Start(); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // wait for all the workers to finish 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < workers.size(); ++i) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers[i]->done_event()->Wait(); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < workers.size(); ++i) { 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) workers[i]->Shutdown(); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) delete workers[i]; 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IPCSyncChannelTest : public testing::Test { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop message_loop_; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------ 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SimpleServer : public Worker { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit SimpleServer(bool pump_during_send) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(Channel::MODE_SERVER, "simpler_server"), 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pump_during_send_(pump_during_send) { } 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendAnswerToLife(pump_during_send_, base::kNoTimeout, true); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool pump_during_send_; 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SimpleClient : public Worker { 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SimpleClient() : Worker(Channel::MODE_CLIENT, "simple_client") { } 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnAnswer(int* answer) OVERRIDE { 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *answer = 42; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Simple(bool pump_during_send) { 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new SimpleServer(pump_during_send)); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new SimpleClient()); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests basic synchronous call 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, Simple) { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Simple(false); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Simple(true); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------ 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Worker classes which override how the sync channel is created to use the 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// two-step initialization (calling the lightweight constructor and then 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ChannelProxy::Init separately) process. 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TwoStepServer : public Worker { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit TwoStepServer(bool create_pipe_now) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(Channel::MODE_SERVER, "simpler_server"), 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) create_pipe_now_(create_pipe_now) { } 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendAnswerToLife(false, base::kNoTimeout, true); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual SyncChannel* CreateChannel() OVERRIDE { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncChannel* channel = new SyncChannel( 3317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) this, ipc_thread().message_loop_proxy().get(), shutdown_event()); 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel->Init(channel_name(), mode(), create_pipe_now_); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool create_pipe_now_; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TwoStepClient : public Worker { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TwoStepClient(bool create_pipe_now) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(Channel::MODE_CLIENT, "simple_client"), 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) create_pipe_now_(create_pipe_now) { } 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnAnswer(int* answer) OVERRIDE { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *answer = 42; 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual SyncChannel* CreateChannel() OVERRIDE { 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncChannel* channel = new SyncChannel( 3527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) this, ipc_thread().message_loop_proxy().get(), shutdown_event()); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel->Init(channel_name(), mode(), create_pipe_now_); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return channel; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool create_pipe_now_; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TwoStep(bool create_server_pipe_now, bool create_client_pipe_now) { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new TwoStepServer(create_server_pipe_now)); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new TwoStepClient(create_client_pipe_now)); 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests basic two-step initialization, where you call the lightweight 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// constructor then Init. 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, TwoStepInitialization) { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TwoStep(false, false); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TwoStep(false, true); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TwoStep(true, false); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TwoStep(true, true); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------ 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DelayClient : public Worker { 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayClient() : Worker(Channel::MODE_CLIENT, "delay_client") { } 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnAnswerDelay(Message* reply_msg) OVERRIDE { 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_msg); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void DelayReply(bool pump_during_send) { 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new SimpleServer(pump_during_send)); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new DelayClient()); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that asynchronous replies work 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, DelayReply) { 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayReply(false); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DelayReply(true); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------ 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NoHangServer : public Worker { 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NoHangServer(WaitableEvent* got_first_reply, bool pump_during_send) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(Channel::MODE_SERVER, "no_hang_server"), 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) got_first_reply_(got_first_reply), 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pump_during_send_(pump_during_send) { } 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendAnswerToLife(pump_during_send_, base::kNoTimeout, true); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) got_first_reply_->Signal(); 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendAnswerToLife(pump_during_send_, base::kNoTimeout, false); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* got_first_reply_; 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool pump_during_send_; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NoHangClient : public Worker { 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit NoHangClient(WaitableEvent* got_first_reply) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(Channel::MODE_CLIENT, "no_hang_client"), 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) got_first_reply_(got_first_reply) { } 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnAnswerDelay(Message* reply_msg) OVERRIDE { 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use the DELAY_REPLY macro so that we can force the reply to be sent 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // before this function returns (when the channel will be reset). 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_msg); 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) got_first_reply_->Wait(); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseChannel(); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* got_first_reply_; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NoHang(bool pump_during_send) { 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent got_first_reply(false, false); 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new NoHangServer(&got_first_reply, pump_during_send)); 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new NoHangClient(&got_first_reply)); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that caller doesn't hang if receiver dies 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, NoHang) { 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NoHang(false); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NoHang(true); 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------ 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class UnblockServer : public Worker { 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UnblockServer(bool pump_during_send, bool delete_during_send) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(Channel::MODE_SERVER, "unblock_server"), 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pump_during_send_(pump_during_send), 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete_during_send_(delete_during_send) { } 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delete_during_send_) { 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use custom code since race conditions mean the answer may or may not be 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // available. 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int answer = 0; 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncMessage* msg = new SyncChannelTestMsg_AnswerToLife(&answer); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pump_during_send_) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg->EnableMessagePumping(); 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(msg); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendAnswerToLife(pump_during_send_, base::kNoTimeout, true); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnDoubleDelay(int in, Message* reply_msg) OVERRIDE { 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, in * 2); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_msg); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delete_during_send_) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetChannel(); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool pump_during_send_; 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool delete_during_send_; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class UnblockClient : public Worker { 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit UnblockClient(bool pump_during_send) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(Channel::MODE_CLIENT, "unblock_client"), 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pump_during_send_(pump_during_send) { } 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnAnswer(int* answer) OVERRIDE { 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDouble(pump_during_send_, true); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *answer = 42; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool pump_during_send_; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Unblock(bool server_pump, bool client_pump, bool delete_during_send) { 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new UnblockServer(server_pump, delete_during_send)); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new UnblockClient(client_pump)); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that the caller unblocks to answer a sync message from the receiver. 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, Unblock) { 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Unblock(false, false, false); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Unblock(false, true, false); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Unblock(true, false, false); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Unblock(true, true, false); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------ 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that the the SyncChannel object can be deleted during a Send. 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, ChannelDeleteDuringSend) { 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Unblock(false, false, true); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Unblock(false, true, true); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Unblock(true, false, true); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Unblock(true, true, true); 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------ 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RecursiveServer : public Worker { 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecursiveServer(bool expected_send_result, bool pump_first, bool pump_second) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(Channel::MODE_SERVER, "recursive_server"), 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_send_result_(expected_send_result), 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pump_first_(pump_first), pump_second_(pump_second) {} 5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDouble(pump_first_, expected_send_result_); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnDouble(int in, int* out) OVERRIDE { 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out = in * 2; 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendAnswerToLife(pump_second_, base::kNoTimeout, expected_send_result_); 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool expected_send_result_, pump_first_, pump_second_; 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RecursiveClient : public Worker { 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecursiveClient(bool pump_during_send, bool close_channel) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(Channel::MODE_CLIENT, "recursive_client"), 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pump_during_send_(pump_during_send), close_channel_(close_channel) {} 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnDoubleDelay(int in, Message* reply_msg) OVERRIDE { 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDouble(pump_during_send_, !close_channel_); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (close_channel_) { 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete reply_msg; 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncChannelTestMsg_Double::WriteReplyParams(reply_msg, in * 2); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_msg); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnAnswerDelay(Message* reply_msg) OVERRIDE { 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (close_channel_) { 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete reply_msg; 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseChannel(); 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_msg); 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool pump_during_send_, close_channel_; 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Recursive( 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool server_pump_first, bool server_pump_second, bool client_pump) { 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back( 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new RecursiveServer(true, server_pump_first, server_pump_second)); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new RecursiveClient(client_pump, false)); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests a server calling Send while another Send is pending. 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, Recursive) { 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Recursive(false, false, false); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Recursive(false, false, true); 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Recursive(false, true, false); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Recursive(false, true, true); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Recursive(true, false, false); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Recursive(true, false, true); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Recursive(true, true, false); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Recursive(true, true, true); 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------ 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void RecursiveNoHang( 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool server_pump_first, bool server_pump_second, bool client_pump) { 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back( 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new RecursiveServer(false, server_pump_first, server_pump_second)); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new RecursiveClient(client_pump, true)); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that if a caller makes a sync call during an existing sync call and 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the receiver dies, neither of the Send() calls hang. 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, RecursiveNoHang) { 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecursiveNoHang(false, false, false); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecursiveNoHang(false, false, true); 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecursiveNoHang(false, true, false); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecursiveNoHang(false, true, true); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecursiveNoHang(true, false, false); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecursiveNoHang(true, false, true); 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecursiveNoHang(true, true, false); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RecursiveNoHang(true, true, true); 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------ 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MultipleServer1 : public Worker { 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit MultipleServer1(bool pump_during_send) 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker("test_channel1", Channel::MODE_SERVER), 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pump_during_send_(pump_during_send) { } 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendDouble(pump_during_send_, true); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool pump_during_send_; 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MultipleClient1 : public Worker { 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MultipleClient1(WaitableEvent* client1_msg_received, 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* client1_can_reply) : 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Worker("test_channel1", Channel::MODE_CLIENT), 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client1_msg_received_(client1_msg_received), 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client1_can_reply_(client1_can_reply) { } 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnDouble(int in, int* out) OVERRIDE { 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client1_msg_received_->Signal(); 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out = in * 2; 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client1_can_reply_->Wait(); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent *client1_msg_received_, *client1_can_reply_; 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MultipleServer2 : public Worker { 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MultipleServer2() : Worker("test_channel2", Channel::MODE_SERVER) { } 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnAnswer(int* result) OVERRIDE { 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *result = 42; 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MultipleClient2 : public Worker { 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MultipleClient2( 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* client1_msg_received, WaitableEvent* client1_can_reply, 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool pump_during_send) 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker("test_channel2", Channel::MODE_CLIENT), 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client1_msg_received_(client1_msg_received), 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client1_can_reply_(client1_can_reply), 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pump_during_send_(pump_during_send) { } 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client1_msg_received_->Wait(); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendAnswerToLife(pump_during_send_, base::kNoTimeout, true); 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client1_can_reply_->Signal(); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent *client1_msg_received_, *client1_can_reply_; 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool pump_during_send_; 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Multiple(bool server_pump, bool client_pump) { 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A shared worker thread so that server1 and server2 run on one thread. 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread worker_thread("Multiple"); 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(worker_thread.Start()); 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Server1 sends a sync msg to client1, which blocks the reply until 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // server2 (which runs on the same worker thread as server1) responds 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to a sync msg from client2. 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent client1_msg_received(false, false); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent client1_can_reply(false, false); 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Worker* worker; 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker = new MultipleServer2(); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker->OverrideThread(&worker_thread); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(worker); 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker = new MultipleClient2( 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &client1_msg_received, &client1_can_reply, client_pump); 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(worker); 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker = new MultipleServer1(server_pump); 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker->OverrideThread(&worker_thread); 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(worker); 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker = new MultipleClient1( 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &client1_msg_received, &client1_can_reply); 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(worker); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that multiple SyncObjects on the same listener thread can unblock each 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// other. 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, Multiple) { 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Multiple(false, false); 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Multiple(false, true); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Multiple(true, false); 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Multiple(true, true); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------ 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class provides server side functionality to test the case where 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// multiple sync channels are in use on the same thread on the client and 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// nested calls are issued. 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class QueuedReplyServer : public Worker { 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QueuedReplyServer(base::Thread* listener_thread, 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& channel_name, 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& reply_text) 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(channel_name, Channel::MODE_SERVER), 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_text_(reply_text) { 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Worker::OverrideThread(listener_thread); 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnNestedTestMsg(Message* reply_msg) OVERRIDE { 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << __FUNCTION__ << " Sending reply: " << reply_text_; 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncChannelNestedTestMsg_String::WriteReplyParams(reply_msg, reply_text_); 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_msg); 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string reply_text_; 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The QueuedReplyClient class provides functionality to test the case where 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// multiple sync channels are in use on the same thread and they make nested 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sync calls, i.e. while the first channel waits for a response it makes a 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sync call on another channel. 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The callstack should unwind correctly, i.e. the outermost call should 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// complete first, and so on. 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class QueuedReplyClient : public Worker { 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QueuedReplyClient(base::Thread* listener_thread, 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& channel_name, 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& expected_text, 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool pump_during_send) 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(channel_name, Channel::MODE_CLIENT), 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pump_during_send_(pump_during_send), 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_text_(expected_text) { 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Worker::OverrideThread(listener_thread); 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string response; 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncMessage* msg = new SyncChannelNestedTestMsg_String(&response); 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pump_during_send_) 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg->EnableMessagePumping(); 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = Send(msg); 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(result); 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(response, expected_text_); 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << __FUNCTION__ << " Received reply: " << response; 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool pump_during_send_; 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string expected_text_; 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void QueuedReply(bool client_pump) { 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A shared worker thread for servers 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread server_worker_thread("QueuedReply_ServerListener"); 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(server_worker_thread.Start()); 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread client_worker_thread("QueuedReply_ClientListener"); 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(client_worker_thread.Start()); 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Worker* worker; 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker = new QueuedReplyServer(&server_worker_thread, 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "QueuedReply_Server1", 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Got first message"); 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(worker); 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker = new QueuedReplyServer(&server_worker_thread, 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "QueuedReply_Server2", 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Got second message"); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(worker); 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker = new QueuedReplyClient(&client_worker_thread, 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "QueuedReply_Server1", 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Got first message", 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_pump); 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(worker); 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker = new QueuedReplyClient(&client_worker_thread, 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "QueuedReply_Server2", 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Got second message", 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client_pump); 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(worker); 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// While a blocking send is in progress, the listener thread might answer other 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// synchronous messages. This tests that if during the response to another 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// message the reply to the original messages comes, it is queued up correctly 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and the original Send is unblocked later. 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We also test that the send call stacks unwind correctly when the channel 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pumps messages while waiting for a response. 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, QueuedReply) { 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QueuedReply(false); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) QueuedReply(true); 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------ 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ChattyClient : public Worker { 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChattyClient() : 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Worker(Channel::MODE_CLIENT, "chatty_client") { } 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnAnswer(int* answer) OVERRIDE { 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The PostMessage limit is 10k. Send 20% more than that. 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kMessageLimit = 10000; 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kMessagesToSend = kMessageLimit * 120 / 100; 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kMessagesToSend; ++i) { 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!SendDouble(false, true)) 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *answer = 42; 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChattyServer(bool pump_during_send) { 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new UnblockServer(pump_during_send, false)); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new ChattyClient()); 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests http://b/1093251 - that sending lots of sync messages while 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the receiver is waiting for a sync reply does not overflow the PostMessage 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// queue. 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, ChattyServer) { 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChattyServer(false); 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChattyServer(true); 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TimeoutServer : public Worker { 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeoutServer(int timeout_ms, 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<bool> timeout_seq, 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool pump_during_send) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(Channel::MODE_SERVER, "timeout_server"), 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_ms_(timeout_ms), 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_seq_(timeout_seq), 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pump_during_send_(pump_during_send) { 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (std::vector<bool>::const_iterator iter = timeout_seq_.begin(); 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != timeout_seq_.end(); ++iter) { 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendAnswerToLife(pump_during_send_, timeout_ms_, !*iter); 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int timeout_ms_; 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<bool> timeout_seq_; 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool pump_during_send_; 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class UnresponsiveClient : public Worker { 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit UnresponsiveClient(std::vector<bool> timeout_seq) 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(Channel::MODE_CLIENT, "unresponsive_client"), 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_seq_(timeout_seq) { 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnAnswerDelay(Message* reply_msg) OVERRIDE { 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!timeout_seq_.empty()); 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!timeout_seq_[0]) { 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncChannelTestMsg_AnswerToLife::WriteReplyParams(reply_msg, 42); 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_msg); 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't reply. 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete reply_msg; 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_seq_.erase(timeout_seq_.begin()); 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (timeout_seq_.empty()) 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Whether we should time-out or respond to the various messages we receive. 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<bool> timeout_seq_; 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SendWithTimeoutOK(bool pump_during_send) { 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<bool> timeout_seq; 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_seq.push_back(false); 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_seq.push_back(false); 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_seq.push_back(false); 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new TimeoutServer(5000, timeout_seq, pump_during_send)); 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new SimpleClient()); 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SendWithTimeoutTimeout(bool pump_during_send) { 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<bool> timeout_seq; 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_seq.push_back(true); 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_seq.push_back(false); 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_seq.push_back(false); 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new TimeoutServer(100, timeout_seq, pump_during_send)); 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new UnresponsiveClient(timeout_seq)); 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SendWithTimeoutMixedOKAndTimeout(bool pump_during_send) { 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<bool> timeout_seq; 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_seq.push_back(true); 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_seq.push_back(false); 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_seq.push_back(false); 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_seq.push_back(true); 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_seq.push_back(false); 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new TimeoutServer(100, timeout_seq, pump_during_send)); 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new UnresponsiveClient(timeout_seq)); 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that SendWithTimeout does not time-out if the response comes back fast 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// enough. 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, SendWithTimeoutOK) { 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendWithTimeoutOK(false); 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendWithTimeoutOK(true); 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that SendWithTimeout does time-out. 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, SendWithTimeoutTimeout) { 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendWithTimeoutTimeout(false); 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendWithTimeoutTimeout(true); 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sends some message that time-out and some that succeed. 9822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(IPCSyncChannelTest, SendWithTimeoutMixedOKAndTimeout) { 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendWithTimeoutMixedOKAndTimeout(false); 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendWithTimeoutMixedOKAndTimeout(true); 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//------------------------------------------------------------------------------ 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void NestedCallback(Worker* server) { 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sleep a bit so that we wake up after the reply has been received. 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(250)); 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server->SendAnswerToLife(true, base::kNoTimeout, true); 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool timeout_occurred = false; 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TimeoutCallback() { 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_occurred = true; 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DoneEventRaceServer : public Worker { 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DoneEventRaceServer() 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(Channel::MODE_SERVER, "done_event_race_server") { } 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 1007c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostTask(FROM_HERE, 1008c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&NestedCallback, this)); 1009c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&TimeoutCallback), 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromSeconds(9)); 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Even though we have a timeout on the Send, it will succeed since for this 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bug, the reply message comes back and is deserialized, however the done 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // event wasn't set. So we indirectly use the timeout task to notice if a 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // timeout occurred. 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendAnswerToLife(true, 10000, true); 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!timeout_occurred); 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests http://b/1474092 - that if after the done_event is set but before 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OnObjectSignaled is called another message is sent out, then after its 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reply comes back OnObjectSignaled will be called for the first message. 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, DoneEventRace) { 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new DoneEventRaceServer()); 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new SimpleClient()); 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------ 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestSyncMessageFilter : public SyncMessageFilter { 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestSyncMessageFilter(base::WaitableEvent* shutdown_event, 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Worker* worker, 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> message_loop) 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : SyncMessageFilter(shutdown_event), 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_(worker), 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_(message_loop) { 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnFilterAdded(Channel* channel) OVERRIDE { 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncMessageFilter::OnFilterAdded(channel); 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_->PostTask( 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&TestSyncMessageFilter::SendMessageOnHelperThread, this)); 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SendMessageOnHelperThread() { 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int answer = 0; 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = Send(new SyncChannelTestMsg_AnswerToLife(&answer)); 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(result); 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(answer, 42); 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_->Done(); 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~TestSyncMessageFilter() {} 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Worker* worker_; 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> message_loop_; 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SyncMessageFilterServer : public Worker { 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncMessageFilterServer() 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(Channel::MODE_SERVER, "sync_message_filter_server"), 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_("helper_thread") { 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread::Options options; 1074c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_.StartWithOptions(options); 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filter_ = new TestSyncMessageFilter(shutdown_event(), this, 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) thread_.message_loop_proxy()); 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel()->AddFilter(filter_.get()); 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread thread_; 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<TestSyncMessageFilter> filter_; 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class provides functionality to test the case that a Send on the sync 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// channel does not crash after the channel has been closed. 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ServerSendAfterClose : public Worker { 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ServerSendAfterClose() 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(Channel::MODE_SERVER, "simpler_server"), 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) send_result_(true) { 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool SendDummy() { 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ListenerThread()->message_loop()->PostTask( 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(base::IgnoreResult(&ServerSendAfterClose::Send), 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) this, new SyncChannelTestMsg_NoArgs)); 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool send_result() const { 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return send_result_; 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 11092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseChannel(); 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool Send(Message* msg) OVERRIDE { 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) send_result_ = Worker::Send(msg); 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return send_result_; 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool send_result_; 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests basic synchronous call 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, SyncMessageFilter) { 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new SyncMessageFilterServer()); 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new SimpleClient()); 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test the case when the channel is closed and a Send is attempted after that. 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, SendAfterClose) { 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ServerSendAfterClose server; 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server.Start(); 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server.done_event()->Wait(); 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server.done_event()->Reset(); 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server.SendDummy(); 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server.done_event()->Wait(); 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(server.send_result()); 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) server.Shutdown(); 11452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------ 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RestrictedDispatchServer : public Worker { 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestrictedDispatchServer(WaitableEvent* sent_ping_event, 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* wait_event) 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker("restricted_channel", Channel::MODE_SERVER), 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sent_ping_event_(sent_ping_event), 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_event_(wait_event) { } 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnDoPing(int ping) { 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Send an asynchronous message that unblocks the caller. 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* msg = new SyncChannelTestMsg_Ping(ping); 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg->set_unblock(true); 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(msg); 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Signal the event after the message has been sent on the channel, on the 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // IPC thread. 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ipc_thread().message_loop()->PostTask( 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&RestrictedDispatchServer::OnPingSent, this)); 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnPingTTL(int ping, int* out) { 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *out = ping; 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) wait_event_->Wait(); 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread* ListenerThread() { return Worker::ListenerThread(); } 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 11762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool OnMessageReceived(const Message& message) OVERRIDE { 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchServer, message) 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs) 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(SyncChannelTestMsg_PingTTL, OnPingTTL) 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, Done) 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnPingSent() { 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sent_ping_event_->Signal(); 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnNoArgs() { } 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* sent_ping_event_; 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* wait_event_; 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class NonRestrictedDispatchServer : public Worker { 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NonRestrictedDispatchServer(WaitableEvent* signal_event) 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker("non_restricted_channel", Channel::MODE_SERVER), 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signal_event_(signal_event) {} 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread* ListenerThread() { return Worker::ListenerThread(); } 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnDoPingTTL(int ping) { 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int value = 0; 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new SyncChannelTestMsg_PingTTL(ping, &value)); 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signal_event_->Signal(); 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool OnMessageReceived(const Message& message) OVERRIDE { 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(NonRestrictedDispatchServer, message) 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs) 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, Done) 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnNoArgs() { } 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* signal_event_; 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RestrictedDispatchClient : public Worker { 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestrictedDispatchClient(WaitableEvent* sent_ping_event, 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestrictedDispatchServer* server, 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NonRestrictedDispatchServer* server2, 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* success) 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker("restricted_channel", Channel::MODE_CLIENT), 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ping_(0), 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_(server), 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server2_(server2), 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success_(success), 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sent_ping_event_(sent_ping_event) {} 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Incoming messages from our channel should only be dispatched when we 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // send a message on that same channel. 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel()->SetRestrictDispatchChannelGroup(1); 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_->ListenerThread()->message_loop()->PostTask( 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&RestrictedDispatchServer::OnDoPing, server_, 1)); 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sent_ping_event_->Wait(); 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new SyncChannelTestMsg_NoArgs); 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ping_ == 1) 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++*success_; 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Send failed to dispatch incoming message on same channel"; 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) non_restricted_channel_.reset( 12497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) new SyncChannel("non_restricted_channel", 12507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Channel::MODE_CLIENT, 12517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) this, 12527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ipc_thread().message_loop_proxy().get(), 12537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) true, 12547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) shutdown_event())); 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_->ListenerThread()->message_loop()->PostTask( 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&RestrictedDispatchServer::OnDoPing, server_, 2)); 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sent_ping_event_->Wait(); 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that the incoming message is *not* dispatched when sending on the 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // non restricted channel. 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(piman): there is a possibility of a false positive race condition 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // here, if the message that was posted on the server-side end of the pipe 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // is not visible yet on the client side, but I don't know how to solve this 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // without hooking into the internals of SyncChannel. I haven't seen it in 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // practice (i.e. not setting SetRestrictDispatchToSameChannel does cause 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the following to fail). 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_restricted_channel_->Send(new SyncChannelTestMsg_NoArgs); 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ping_ == 1) 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++*success_; 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Send dispatched message from restricted channel"; 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new SyncChannelTestMsg_NoArgs); 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ping_ == 2) 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++*success_; 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Send failed to dispatch incoming message on same channel"; 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that the incoming message on the non-restricted channel is 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // dispatched when sending on the restricted channel. 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server2_->ListenerThread()->message_loop()->PostTask( 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&NonRestrictedDispatchServer::OnDoPingTTL, server2_, 3)); 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int value = 0; 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new SyncChannelTestMsg_PingTTL(4, &value)); 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ping_ == 3 && value == 4) 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++*success_; 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Send failed to dispatch message from unrestricted channel"; 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_restricted_channel_->Send(new SyncChannelTestMsg_Done); 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_restricted_channel_.reset(); 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new SyncChannelTestMsg_Done); 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 12982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool OnMessageReceived(const Message& message) OVERRIDE { 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchClient, message) 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Ping, OnPing) 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER_DELAY_REPLY(SyncChannelTestMsg_PingTTL, OnPingTTL) 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnPing(int ping) { 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ping_ = ping; 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnPingTTL(int ping, IPC::Message* reply) { 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ping_ = ping; 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This message comes from the NonRestrictedDispatchServer, we have to send 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the reply back manually. 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncChannelTestMsg_PingTTL::WriteReplyParams(reply, ping); 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) non_restricted_channel_->Send(reply); 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ping_; 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestrictedDispatchServer* server_; 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NonRestrictedDispatchServer* server2_; 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* success_; 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* sent_ping_event_; 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SyncChannel> non_restricted_channel_; 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, RestrictedDispatch) { 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent sent_ping_event(false, false); 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent wait_event(false, false); 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestrictedDispatchServer* server = 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new RestrictedDispatchServer(&sent_ping_event, &wait_event); 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NonRestrictedDispatchServer* server2 = 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new NonRestrictedDispatchServer(&wait_event); 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int success = 0; 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(server); 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(server2); 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new RestrictedDispatchClient( 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &sent_ping_event, server, server2, &success)); 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(4, success); 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------ 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test case inspired by crbug.com/108491 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We create two servers that use the same ListenerThread but have 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SetRestrictDispatchToSameChannel set to true. 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We create clients, then use some specific WaitableEvent wait/signalling to 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ensure that messages get dispatched in a way that causes a deadlock due to 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a nested dispatch and an eligible message in a higher-level dispatch's 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// delayed_queue. Specifically, we start with client1 about so send an 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// unblocking message to server1, while the shared listener thread for the 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// servers server1 and server2 is about to send a non-unblocking message to 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// client1. At the same time, client2 will be about to send an unblocking 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// message to server2. Server1 will handle the client1->server1 message by 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// telling server2 to send a non-unblocking message to client2. 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// What should happen is that the send to server2 should find the pending, 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// same-context client2->server2 message to dispatch, causing client2 to 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// unblock then handle the server2->client2 message, so that the shared 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// servers' listener thread can then respond to the client1->server1 message. 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Then client1 can handle the non-unblocking server1->client1 message. 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The old code would end up in a state where the server2->client2 message is 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// sent, but the client2->server2 message (which is eligible for dispatch, and 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which is what client2 is waiting for) is stashed in a local delayed_queue 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that has server1's channel context, causing a deadlock. 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// WaitableEvents in the events array are used to: 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// event 0: indicate to client1 that server listener is in OnDoServerTask 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// event 1: indicate to client1 that client2 listener is in OnDoClient2Task 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// event 2: indicate to server1 that client2 listener is in OnDoClient2Task 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// event 3: indicate to client2 that server listener is in OnDoServerTask 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RestrictedDispatchDeadlockServer : public Worker { 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestrictedDispatchDeadlockServer(int server_num, 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* server_ready_event, 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent** events, 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestrictedDispatchDeadlockServer* peer) 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(server_num == 1 ? "channel1" : "channel2", Channel::MODE_SERVER), 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_num_(server_num), 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_ready_event_(server_ready_event), 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_(events), 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) peer_(peer) { } 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnDoServerTask() { 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_[3]->Signal(); 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_[2]->Wait(); 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_[0]->Signal(); 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SendMessageToClient(); 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel()->SetRestrictDispatchChannelGroup(1); 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_ready_event_->Signal(); 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread* ListenerThread() { return Worker::ListenerThread(); } 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 14002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool OnMessageReceived(const Message& message) OVERRIDE { 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchDeadlockServer, message) 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs) 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, Done) 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnNoArgs() { 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (server_num_ == 1) { 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(peer_ != NULL); 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) peer_->SendMessageToClient(); 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SendMessageToClient() { 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* msg = new SyncChannelTestMsg_NoArgs; 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) msg->set_unblock(false); 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!msg->should_unblock()); 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(msg); 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int server_num_; 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* server_ready_event_; 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent** events_; 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestrictedDispatchDeadlockServer* peer_; 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RestrictedDispatchDeadlockClient2 : public Worker { 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestrictedDispatchDeadlockClient2(RestrictedDispatchDeadlockServer* server, 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* server_ready_event, 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent** events) 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker("channel2", Channel::MODE_CLIENT), 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_ready_event_(server_ready_event), 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_(events), 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) received_msg_(false), 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) received_noarg_reply_(false), 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_issued_(false) {} 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_ready_event_->Wait(); 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnDoClient2Task() { 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_[3]->Wait(); 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_[1]->Signal(); 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_[2]->Signal(); 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(received_msg_ == false); 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* message = new SyncChannelTestMsg_NoArgs; 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message->set_unblock(true); 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(message); 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) received_noarg_reply_ = true; 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread* ListenerThread() { return Worker::ListenerThread(); } 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 14582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool OnMessageReceived(const Message& message) OVERRIDE { 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchDeadlockClient2, message) 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs) 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnNoArgs() { 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) received_msg_ = true; 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PossiblyDone(); 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PossiblyDone() { 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (received_noarg_reply_ && received_msg_) { 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(done_issued_ == false); 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_issued_ = true; 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new SyncChannelTestMsg_Done); 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* server_ready_event_; 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent** events_; 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool received_msg_; 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool received_noarg_reply_; 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool done_issued_; 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RestrictedDispatchDeadlockClient1 : public Worker { 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestrictedDispatchDeadlockClient1(RestrictedDispatchDeadlockServer* server, 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestrictedDispatchDeadlockClient2* peer, 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* server_ready_event, 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent** events) 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker("channel1", Channel::MODE_CLIENT), 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_(server), 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) peer_(peer), 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_ready_event_(server_ready_event), 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_(events), 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) received_msg_(false), 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) received_noarg_reply_(false), 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_issued_(false) {} 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_ready_event_->Wait(); 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_->ListenerThread()->message_loop()->PostTask( 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&RestrictedDispatchDeadlockServer::OnDoServerTask, server_)); 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) peer_->ListenerThread()->message_loop()->PostTask( 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&RestrictedDispatchDeadlockClient2::OnDoClient2Task, peer_)); 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_[0]->Wait(); 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events_[1]->Wait(); 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(received_msg_ == false); 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* message = new SyncChannelTestMsg_NoArgs; 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message->set_unblock(true); 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(message); 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) received_noarg_reply_ = true; 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PossiblyDone(); 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread* ListenerThread() { return Worker::ListenerThread(); } 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 15222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool OnMessageReceived(const Message& message) OVERRIDE { 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchDeadlockClient1, message) 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(SyncChannelTestMsg_NoArgs, OnNoArgs) 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnNoArgs() { 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) received_msg_ = true; 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PossiblyDone(); 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PossiblyDone() { 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (received_noarg_reply_ && received_msg_) { 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(done_issued_ == false); 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) done_issued_ = true; 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new SyncChannelTestMsg_Done); 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestrictedDispatchDeadlockServer* server_; 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestrictedDispatchDeadlockClient2* peer_; 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* server_ready_event_; 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent** events_; 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool received_msg_; 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool received_noarg_reply_; 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool done_issued_; 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, RestrictedDispatchDeadlock) { 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A shared worker thread so that server1 and server2 run on one thread. 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread worker_thread("RestrictedDispatchDeadlock"); 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(worker_thread.Start()); 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent server1_ready(false, false); 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent server2_ready(false, false); 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent event0(false, false); 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent event1(false, false); 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent event2(false, false); 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent event3(false, false); 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* events[4] = {&event0, &event1, &event2, &event3}; 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestrictedDispatchDeadlockServer* server1; 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestrictedDispatchDeadlockServer* server2; 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestrictedDispatchDeadlockClient1* client1; 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestrictedDispatchDeadlockClient2* client2; 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server2 = new RestrictedDispatchDeadlockServer(2, &server2_ready, events, 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NULL); 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server2->OverrideThread(&worker_thread); 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(server2); 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client2 = new RestrictedDispatchDeadlockClient2(server2, &server2_ready, 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) events); 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(client2); 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server1 = new RestrictedDispatchDeadlockServer(1, &server1_ready, events, 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server2); 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server1->OverrideThread(&worker_thread); 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(server1); 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) client1 = new RestrictedDispatchDeadlockClient1(server1, client2, 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &server1_ready, events); 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(client1); 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------ 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test case inspired by crbug.com/120530 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We create 4 workers that pipe to each other W1->W2->W3->W4->W1 then we send a 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// message that recurses through 3, 4 or 5 steps to make sure, say, W1 can 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// re-enter when called from W4 while it's sending a message to W2. 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The first worker drives the whole test so it must be treated specially. 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RestrictedDispatchPipeWorker : public Worker { 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RestrictedDispatchPipeWorker( 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string &channel1, 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* event1, 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string &channel2, 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* event2, 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int group, 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* success) 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(channel1, Channel::MODE_SERVER), 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event1_(event1), 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event2_(event2), 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_channel_name_(channel2), 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) group_(group), 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success_(success) { 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnPingTTL(int ping, int* ret) { 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *ret = 0; 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!ping) 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_channel_->Send(new SyncChannelTestMsg_PingTTL(ping - 1, ret)); 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++*ret; 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnDone() { 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_first()) 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_channel_->Send(new SyncChannelTestMsg_Done); 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_channel_.reset(); 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel()->SetRestrictDispatchChannelGroup(group_); 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (is_first()) 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event1_->Signal(); 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event2_->Wait(); 16407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) other_channel_.reset( 16417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) new SyncChannel(other_channel_name_, 16427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Channel::MODE_CLIENT, 16437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) this, 16447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ipc_thread().message_loop_proxy().get(), 16457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) true, 16467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) shutdown_event())); 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_channel_->SetRestrictDispatchChannelGroup(group_); 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!is_first()) { 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event1_->Signal(); 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *success_ = 0; 16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int value = 0; 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnPingTTL(3, &value); 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *success_ += (value == 3); 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnPingTTL(4, &value); 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *success_ += (value == 4); 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnPingTTL(5, &value); 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *success_ += (value == 5); 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_channel_->Send(new SyncChannelTestMsg_Done); 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) other_channel_.reset(); 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_first() { return !!success_; } 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 16682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool OnMessageReceived(const Message& message) OVERRIDE { 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(RestrictedDispatchPipeWorker, message) 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(SyncChannelTestMsg_PingTTL, OnPingTTL) 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Done, OnDone) 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SyncChannel> other_channel_; 16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* event1_; 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* event2_; 16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string other_channel_name_; 16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int group_; 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int* success_; 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, RestrictedDispatch4WayDeadlock) { 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int success = 0; 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent event0(true, false); 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent event1(true, false); 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent event2(true, false); 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent event3(true, false); 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new RestrictedDispatchPipeWorker( 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "channel0", &event0, "channel1", &event1, 1, &success)); 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new RestrictedDispatchPipeWorker( 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "channel1", &event1, "channel2", &event2, 2, NULL)); 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new RestrictedDispatchPipeWorker( 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "channel2", &event2, "channel3", &event3, 3, NULL)); 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new RestrictedDispatchPipeWorker( 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "channel3", &event3, "channel0", &event0, 4, NULL)); 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(3, success); 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------ 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test case inspired by crbug.com/122443 17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We want to make sure a reply message with the unblock flag set correctly 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// behaves as a reply, not a regular message. 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We have 3 workers. Server1 will send a message to Server2 (which will block), 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// during which it will dispatch a message comming from Client, at which point 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it will send another message to Server2. While sending that second message it 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// will receive a reply from Server1 with the unblock flag. 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ReentrantReplyServer1 : public Worker { 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReentrantReplyServer1(WaitableEvent* server_ready) 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker("reentrant_reply1", Channel::MODE_SERVER), 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_ready_(server_ready) { } 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 17207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) server2_channel_.reset( 17217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) new SyncChannel("reentrant_reply2", 17227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) Channel::MODE_CLIENT, 17237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) this, 17247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ipc_thread().message_loop_proxy().get(), 17257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) true, 17267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) shutdown_event())); 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_ready_->Signal(); 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* msg = new SyncChannelTestMsg_Reentrant1(); 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server2_channel_->Send(msg); 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server2_channel_.reset(); 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 17352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool OnMessageReceived(const Message& message) OVERRIDE { 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(ReentrantReplyServer1, message) 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Reentrant2, OnReentrant2) 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_REPLY_HANDLER(OnReply) 17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnReentrant2() { 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* msg = new SyncChannelTestMsg_Reentrant3(); 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server2_channel_->Send(msg); 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnReply(const Message& message) { 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we get here, the Send() will never receive the reply (thus would 17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // hang), so abort instead. 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(FATAL) << "Reply message was dispatched"; 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* server_ready_; 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<SyncChannel> server2_channel_; 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ReentrantReplyServer2 : public Worker { 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReentrantReplyServer2() 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker("reentrant_reply2", Channel::MODE_SERVER), 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_(NULL) { } 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 17652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool OnMessageReceived(const Message& message) OVERRIDE { 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_BEGIN_MESSAGE_MAP(ReentrantReplyServer2, message) 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER_DELAY_REPLY( 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncChannelTestMsg_Reentrant1, OnReentrant1) 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_MESSAGE_HANDLER(SyncChannelTestMsg_Reentrant3, OnReentrant3) 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IPC_END_MESSAGE_MAP() 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnReentrant1(Message* reply) { 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!reply_); 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_ = reply; 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void OnReentrant3() { 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(reply_); 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* reply = reply_; 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_ = NULL; 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply->set_unblock(true); 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply); 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Message* reply_; 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ReentrantReplyClient : public Worker { 17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReentrantReplyClient(WaitableEvent* server_ready) 17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker("reentrant_reply1", Channel::MODE_CLIENT), 17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_ready_(server_ready) { } 17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) server_ready_->Wait(); 17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(new SyncChannelTestMsg_Reentrant2()); 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent* server_ready_; 18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, ReentrantReply) { 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WaitableEvent server_ready(false, false); 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new ReentrantReplyServer2()); 18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new ReentrantReplyServer1(&server_ready)); 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(new ReentrantReplyClient(&server_ready)); 18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//------------------------------------------------------------------------------ 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Generate a validated channel ID using Channel::GenerateVerifiedChannelID(). 18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VerifiedServer : public Worker { 18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VerifiedServer(base::Thread* listener_thread, 18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& channel_name, 18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& reply_text) 18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(channel_name, Channel::MODE_SERVER), 18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reply_text_(reply_text) { 18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Worker::OverrideThread(listener_thread); 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnNestedTestMsg(Message* reply_msg) OVERRIDE { 18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << __FUNCTION__ << " Sending reply: " << reply_text_; 18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncChannelNestedTestMsg_String::WriteReplyParams(reply_msg, reply_text_); 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Send(reply_msg); 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(channel()->peer_pid(), base::GetCurrentProcId()); 18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string reply_text_; 18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class VerifiedClient : public Worker { 18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VerifiedClient(base::Thread* listener_thread, 18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& channel_name, 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& expected_text) 18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Worker(channel_name, Channel::MODE_CLIENT), 18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_text_(expected_text) { 18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Worker::OverrideThread(listener_thread); 18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void Run() OVERRIDE { 18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string response; 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncMessage* msg = new SyncChannelNestedTestMsg_String(&response); 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = Send(msg); 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(result); 18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(response, expected_text_); 18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // expected_text_ is only used in the above DCHECK. This line suppresses the 18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // "unused private field" warning in release builds. 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (void)expected_text_; 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VLOG(1) << __FUNCTION__ << " Received reply: " << response; 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(channel()->peer_pid(), base::GetCurrentProcId()); 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Done(); 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string expected_text_; 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Verified() { 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<Worker*> workers; 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A shared worker thread for servers 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread server_worker_thread("Verified_ServerListener"); 18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(server_worker_thread.Start()); 18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Thread client_worker_thread("Verified_ClientListener"); 18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(client_worker_thread.Start()); 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string channel_id = Channel::GenerateVerifiedChannelID("Verified"); 18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Worker* worker; 18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker = new VerifiedServer(&server_worker_thread, 18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_id, 18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Got first message"); 18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(worker); 18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker = new VerifiedClient(&client_worker_thread, 18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) channel_id, 18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Got first message"); 18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) workers.push_back(worker); 18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RunTest(workers); 18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Windows needs to send an out-of-band secret to verify the client end of the 18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// channel. Test that we still connect correctly in that case. 18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IPCSyncChannelTest, Verified) { 19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Verified(); 19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace IPC 1905