1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/chromium/src/chrome/common/ipc_sync_channel.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,159 @@ 1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1.5 +// Use of this source code is governed by a BSD-style license that can be 1.6 +// found in the LICENSE file. 1.7 + 1.8 +#ifndef CHROME_COMMON_IPC_SYNC_SENDER_H__ 1.9 +#define CHROME_COMMON_IPC_SYNC_SENDER_H__ 1.10 + 1.11 +#include <string> 1.12 +#include <deque> 1.13 +#include "base/basictypes.h" 1.14 +#include "base/lock.h" 1.15 +#include "base/ref_counted.h" 1.16 +#include "base/scoped_handle.h" 1.17 +#include "base/waitable_event.h" 1.18 +#include "base/waitable_event_watcher.h" 1.19 +#include "chrome/common/ipc_channel_proxy.h" 1.20 + 1.21 +namespace IPC { 1.22 + 1.23 +class SyncMessage; 1.24 +class MessageReplyDeserializer; 1.25 + 1.26 +// This is similar to IPC::ChannelProxy, with the added feature of supporting 1.27 +// sending synchronous messages. 1.28 +// Note that care must be taken that the lifetime of the ipc_thread argument 1.29 +// is more than this object. If the message loop goes away while this object 1.30 +// is running and it's used to send a message, then it will use the invalid 1.31 +// message loop pointer to proxy it to the ipc thread. 1.32 +class SyncChannel : public ChannelProxy, 1.33 + public base::WaitableEventWatcher::Delegate { 1.34 + public: 1.35 + SyncChannel(const std::wstring& channel_id, Channel::Mode mode, 1.36 + Channel::Listener* listener, MessageFilter* filter, 1.37 + MessageLoop* ipc_message_loop, bool create_pipe_now, 1.38 + base::WaitableEvent* shutdown_event); 1.39 + ~SyncChannel(); 1.40 + 1.41 + virtual bool Send(Message* message); 1.42 + virtual bool SendWithTimeout(Message* message, int timeout_ms); 1.43 + 1.44 + // Whether we allow sending messages with no time-out. 1.45 + void set_sync_messages_with_no_timeout_allowed(bool value) { 1.46 + sync_messages_with_no_timeout_allowed_ = value; 1.47 + } 1.48 + 1.49 + protected: 1.50 + class ReceivedSyncMsgQueue; 1.51 + friend class ReceivedSyncMsgQueue; 1.52 + 1.53 + // SyncContext holds the per object data for SyncChannel, so that SyncChannel 1.54 + // can be deleted while it's being used in a different thread. See 1.55 + // ChannelProxy::Context for more information. 1.56 + class SyncContext : public Context, 1.57 + public base::WaitableEventWatcher::Delegate { 1.58 + public: 1.59 + SyncContext(Channel::Listener* listener, 1.60 + MessageFilter* filter, 1.61 + MessageLoop* ipc_thread, 1.62 + base::WaitableEvent* shutdown_event); 1.63 + 1.64 + ~SyncContext(); 1.65 + 1.66 + // Adds information about an outgoing sync message to the context so that 1.67 + // we know how to deserialize the reply. 1.68 + void Push(IPC::SyncMessage* sync_msg); 1.69 + 1.70 + // Cleanly remove the top deserializer (and throw it away). Returns the 1.71 + // result of the Send call for that message. 1.72 + bool Pop(); 1.73 + 1.74 + // Returns an event that's set when the send is complete, timed out or the 1.75 + // process shut down. 1.76 + base::WaitableEvent* GetSendDoneEvent(); 1.77 + 1.78 + // Returns an event that's set when an incoming message that's not the reply 1.79 + // needs to get dispatched (by calling SyncContext::DispatchMessages). 1.80 + base::WaitableEvent* GetDispatchEvent(); 1.81 + 1.82 + void DispatchMessages(); 1.83 + 1.84 + // Checks if the given message is blocking the listener thread because of a 1.85 + // synchronous send. If it is, the thread is unblocked and true is 1.86 + // returned. Otherwise the function returns false. 1.87 + bool TryToUnblockListener(const Message* msg); 1.88 + 1.89 + // Called on the IPC thread when a sync send that runs a nested message loop 1.90 + // times out. 1.91 + void OnSendTimeout(int message_id); 1.92 + 1.93 + base::WaitableEvent* shutdown_event() { return shutdown_event_; } 1.94 + 1.95 + private: 1.96 + // IPC::ChannelProxy methods that we override. 1.97 + 1.98 + // Called on the listener thread. 1.99 + virtual void Clear(); 1.100 + 1.101 + // Called on the IPC thread. 1.102 + virtual void OnMessageReceived(const Message& msg); 1.103 + virtual void OnChannelError(); 1.104 + virtual void OnChannelOpened(); 1.105 + virtual void OnChannelClosed(); 1.106 + 1.107 + // Cancels all pending Send calls. 1.108 + void CancelPendingSends(); 1.109 + 1.110 + // WaitableEventWatcher::Delegate implementation. 1.111 + virtual void OnWaitableEventSignaled(base::WaitableEvent* arg); 1.112 + 1.113 + // When sending a synchronous message, this structure contains an object 1.114 + // that knows how to deserialize the response. 1.115 + struct PendingSyncMsg { 1.116 + PendingSyncMsg(int id, IPC::MessageReplyDeserializer* d, 1.117 + base::WaitableEvent* e) : 1.118 + id(id), deserializer(d), done_event(e), send_result(false) { } 1.119 + int id; 1.120 + IPC::MessageReplyDeserializer* deserializer; 1.121 + base::WaitableEvent* done_event; 1.122 + bool send_result; 1.123 + }; 1.124 + 1.125 + typedef std::deque<PendingSyncMsg> PendingSyncMessageQueue; 1.126 + PendingSyncMessageQueue deserializers_; 1.127 + Lock deserializers_lock_; 1.128 + 1.129 + scoped_refptr<ReceivedSyncMsgQueue> received_sync_msgs_; 1.130 + 1.131 + base::WaitableEvent* shutdown_event_; 1.132 + base::WaitableEventWatcher shutdown_watcher_; 1.133 + }; 1.134 + 1.135 + private: 1.136 + // WaitableEventWatcher::Delegate implementation. 1.137 + virtual void OnWaitableEventSignaled(base::WaitableEvent* arg); 1.138 + 1.139 + SyncContext* sync_context() { 1.140 + return reinterpret_cast<SyncContext*>(context()); 1.141 + } 1.142 + 1.143 + // Both these functions wait for a reply, timeout or process shutdown. The 1.144 + // latter one also runs a nested message loop in the meantime. 1.145 + void WaitForReply(base::WaitableEvent* pump_messages_event); 1.146 + 1.147 + // Runs a nested message loop until a reply arrives, times out, or the process 1.148 + // shuts down. 1.149 + void WaitForReplyWithNestedMessageLoop(); 1.150 + 1.151 + bool sync_messages_with_no_timeout_allowed_; 1.152 + 1.153 + // Used to signal events between the IPC and listener threads. 1.154 + base::WaitableEventWatcher send_done_watcher_; 1.155 + base::WaitableEventWatcher dispatch_watcher_; 1.156 + 1.157 + DISALLOW_EVIL_CONSTRUCTORS(SyncChannel); 1.158 +}; 1.159 + 1.160 +} // namespace IPC 1.161 + 1.162 +#endif // CHROME_COMMON_IPC_SYNC_SENDER_H__