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_message_filter.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/location.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h" 125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "ipc/ipc_channel.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ipc/ipc_sync_message.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::MessageLoopProxy; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace IPC { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncMessageFilter::SyncMessageFilter(base::WaitableEvent* shutdown_event) 20f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) : sender_(NULL), 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) listener_loop_(MessageLoopProxy::current()), 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) shutdown_event_(shutdown_event) { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncMessageFilter::Send(Message* message) { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 28868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!io_loop_.get()) { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete message; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!message->is_sync()) { 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_loop_->PostTask( 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&SyncMessageFilter::SendOnIOThread, this, message)); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent done_event(true, false); 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingSyncMsg pending_message( 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SyncMessage::GetMessageId(*message), 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<SyncMessage*>(message)->GetReplyDeserializer(), 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &done_event); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Can't use this class on the main thread or else it can lead to deadlocks. 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Also by definition, can't use this on IO thread since we're blocking it. 507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(MessageLoopProxy::current().get() != listener_loop_.get()); 517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) DCHECK(MessageLoopProxy::current().get() != io_loop_.get()); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_sync_messages_.insert(&pending_message); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_loop_->PostTask( 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, base::Bind(&SyncMessageFilter::SendOnIOThread, this, message)); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent* events[2] = { shutdown_event_, &done_event }; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent::WaitMany(events, 2); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete pending_message.deserializer; 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_sync_messages_.erase(&pending_message); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pending_message.send_result; 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 70f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void SyncMessageFilter::OnFilterAdded(Sender* sender) { 71f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sender_ = sender; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) io_loop_ = MessageLoopProxy::current(); 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncMessageFilter::OnChannelError() { 77f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sender_ = NULL; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignalAllEvents(); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncMessageFilter::OnChannelClosing() { 82f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sender_ = NULL; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignalAllEvents(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SyncMessageFilter::OnMessageReceived(const Message& message) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (PendingSyncMessages::iterator iter = pending_sync_messages_.begin(); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != pending_sync_messages_.end(); ++iter) { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SyncMessage::IsMessageReplyTo(message, (*iter)->id)) { 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!message.is_reply_error()) { 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*iter)->send_result = 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*iter)->deserializer->SerializeOutputParameters(message); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*iter)->done_event->Signal(); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SyncMessageFilter::~SyncMessageFilter() { 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncMessageFilter::SendOnIOThread(Message* message) { 107f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (sender_) { 108f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) sender_->Send(message); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (message->is_sync()) { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We don't know which thread sent it, but it doesn't matter, just signal 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // them all. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SignalAllEvents(); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete message; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SyncMessageFilter::SignalAllEvents() { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (PendingSyncMessages::iterator iter = pending_sync_messages_.begin(); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) iter != pending_sync_messages_.end(); ++iter) { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*iter)->done_event->Signal(); 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace IPC 130