Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_COMMON_IPC_SYNC_SENDER_H__
6 #define CHROME_COMMON_IPC_SYNC_SENDER_H__
8 #include <string>
9 #include <deque>
10 #include "base/basictypes.h"
11 #include "base/lock.h"
12 #include "base/ref_counted.h"
13 #include "base/scoped_handle.h"
14 #include "base/waitable_event.h"
15 #include "base/waitable_event_watcher.h"
16 #include "chrome/common/ipc_channel_proxy.h"
18 namespace IPC {
20 class SyncMessage;
21 class MessageReplyDeserializer;
23 // This is similar to IPC::ChannelProxy, with the added feature of supporting
24 // sending synchronous messages.
25 // Note that care must be taken that the lifetime of the ipc_thread argument
26 // is more than this object. If the message loop goes away while this object
27 // is running and it's used to send a message, then it will use the invalid
28 // message loop pointer to proxy it to the ipc thread.
29 class SyncChannel : public ChannelProxy,
30 public base::WaitableEventWatcher::Delegate {
31 public:
32 SyncChannel(const std::wstring& channel_id, Channel::Mode mode,
33 Channel::Listener* listener, MessageFilter* filter,
34 MessageLoop* ipc_message_loop, bool create_pipe_now,
35 base::WaitableEvent* shutdown_event);
36 ~SyncChannel();
38 virtual bool Send(Message* message);
39 virtual bool SendWithTimeout(Message* message, int timeout_ms);
41 // Whether we allow sending messages with no time-out.
42 void set_sync_messages_with_no_timeout_allowed(bool value) {
43 sync_messages_with_no_timeout_allowed_ = value;
44 }
46 protected:
47 class ReceivedSyncMsgQueue;
48 friend class ReceivedSyncMsgQueue;
50 // SyncContext holds the per object data for SyncChannel, so that SyncChannel
51 // can be deleted while it's being used in a different thread. See
52 // ChannelProxy::Context for more information.
53 class SyncContext : public Context,
54 public base::WaitableEventWatcher::Delegate {
55 public:
56 SyncContext(Channel::Listener* listener,
57 MessageFilter* filter,
58 MessageLoop* ipc_thread,
59 base::WaitableEvent* shutdown_event);
61 ~SyncContext();
63 // Adds information about an outgoing sync message to the context so that
64 // we know how to deserialize the reply.
65 void Push(IPC::SyncMessage* sync_msg);
67 // Cleanly remove the top deserializer (and throw it away). Returns the
68 // result of the Send call for that message.
69 bool Pop();
71 // Returns an event that's set when the send is complete, timed out or the
72 // process shut down.
73 base::WaitableEvent* GetSendDoneEvent();
75 // Returns an event that's set when an incoming message that's not the reply
76 // needs to get dispatched (by calling SyncContext::DispatchMessages).
77 base::WaitableEvent* GetDispatchEvent();
79 void DispatchMessages();
81 // Checks if the given message is blocking the listener thread because of a
82 // synchronous send. If it is, the thread is unblocked and true is
83 // returned. Otherwise the function returns false.
84 bool TryToUnblockListener(const Message* msg);
86 // Called on the IPC thread when a sync send that runs a nested message loop
87 // times out.
88 void OnSendTimeout(int message_id);
90 base::WaitableEvent* shutdown_event() { return shutdown_event_; }
92 private:
93 // IPC::ChannelProxy methods that we override.
95 // Called on the listener thread.
96 virtual void Clear();
98 // Called on the IPC thread.
99 virtual void OnMessageReceived(const Message& msg);
100 virtual void OnChannelError();
101 virtual void OnChannelOpened();
102 virtual void OnChannelClosed();
104 // Cancels all pending Send calls.
105 void CancelPendingSends();
107 // WaitableEventWatcher::Delegate implementation.
108 virtual void OnWaitableEventSignaled(base::WaitableEvent* arg);
110 // When sending a synchronous message, this structure contains an object
111 // that knows how to deserialize the response.
112 struct PendingSyncMsg {
113 PendingSyncMsg(int id, IPC::MessageReplyDeserializer* d,
114 base::WaitableEvent* e) :
115 id(id), deserializer(d), done_event(e), send_result(false) { }
116 int id;
117 IPC::MessageReplyDeserializer* deserializer;
118 base::WaitableEvent* done_event;
119 bool send_result;
120 };
122 typedef std::deque<PendingSyncMsg> PendingSyncMessageQueue;
123 PendingSyncMessageQueue deserializers_;
124 Lock deserializers_lock_;
126 scoped_refptr<ReceivedSyncMsgQueue> received_sync_msgs_;
128 base::WaitableEvent* shutdown_event_;
129 base::WaitableEventWatcher shutdown_watcher_;
130 };
132 private:
133 // WaitableEventWatcher::Delegate implementation.
134 virtual void OnWaitableEventSignaled(base::WaitableEvent* arg);
136 SyncContext* sync_context() {
137 return reinterpret_cast<SyncContext*>(context());
138 }
140 // Both these functions wait for a reply, timeout or process shutdown. The
141 // latter one also runs a nested message loop in the meantime.
142 void WaitForReply(base::WaitableEvent* pump_messages_event);
144 // Runs a nested message loop until a reply arrives, times out, or the process
145 // shuts down.
146 void WaitForReplyWithNestedMessageLoop();
148 bool sync_messages_with_no_timeout_allowed_;
150 // Used to signal events between the IPC and listener threads.
151 base::WaitableEventWatcher send_done_watcher_;
152 base::WaitableEventWatcher dispatch_watcher_;
154 DISALLOW_EVIL_CONSTRUCTORS(SyncChannel);
155 };
157 } // namespace IPC
159 #endif // CHROME_COMMON_IPC_SYNC_SENDER_H__