ipc/chromium/src/chrome/common/ipc_sync_channel.h

Wed, 31 Dec 2014 13:27:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 13:27:57 +0100
branch
TOR_BUG_3246
changeset 6
8bccb770b82d
permissions
-rw-r--r--

Ignore runtime configuration files generated during quality assurance.

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

mercurial