blob: cb88f47b2b57a89d8edec317619ab4238476f6ac [file] [log] [blame]
[email protected]5a3b9142009-08-28 21:03:171// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]5a3b9142009-08-28 21:03:175#ifndef IPC_IPC_SYNC_SENDER_H__
6#define IPC_IPC_SYNC_SENDER_H__
initial.commit09911bf2008-07-26 23:55:297
initial.commit09911bf2008-07-26 23:55:298#include <string>
[email protected]3cdb7af812008-10-24 19:21:139#include <deque>
[email protected]7bf730952009-05-29 09:31:1510
initial.commit09911bf2008-07-26 23:55:2911#include "base/basictypes.h"
12#include "base/lock.h"
13#include "base/ref_counted.h"
[email protected]1c4947f2009-01-15 22:25:1114#include "base/waitable_event_watcher.h"
[email protected]946d1b22009-07-22 23:57:2115#include "ipc/ipc_channel_proxy.h"
initial.commit09911bf2008-07-26 23:55:2916
[email protected]7bf730952009-05-29 09:31:1517namespace base {
18class WaitableEvent;
19};
20
initial.commit09911bf2008-07-26 23:55:2921namespace IPC {
22
23class SyncMessage;
[email protected]1c4947f2009-01-15 22:25:1124class MessageReplyDeserializer;
initial.commit09911bf2008-07-26 23:55:2925
26// This is similar to IPC::ChannelProxy, with the added feature of supporting
27// sending synchronous messages.
28// Note that care must be taken that the lifetime of the ipc_thread argument
29// is more than this object. If the message loop goes away while this object
30// is running and it's used to send a message, then it will use the invalid
31// message loop pointer to proxy it to the ipc thread.
[email protected]3cdb7af812008-10-24 19:21:1332class SyncChannel : public ChannelProxy,
[email protected]1c4947f2009-01-15 22:25:1133 public base::WaitableEventWatcher::Delegate {
initial.commit09911bf2008-07-26 23:55:2934 public:
[email protected]9a3a293b2009-06-04 22:28:1635 SyncChannel(const std::string& channel_id, Channel::Mode mode,
[email protected]d65cab7a2008-08-12 01:25:4136 Channel::Listener* listener, MessageFilter* filter,
37 MessageLoop* ipc_message_loop, bool create_pipe_now,
[email protected]1c4947f2009-01-15 22:25:1138 base::WaitableEvent* shutdown_event);
[email protected]17acbb52009-08-28 17:29:0339 virtual ~SyncChannel();
initial.commit09911bf2008-07-26 23:55:2940
41 virtual bool Send(Message* message);
[email protected]d65cab7a2008-08-12 01:25:4142 virtual bool SendWithTimeout(Message* message, int timeout_ms);
initial.commit09911bf2008-07-26 23:55:2943
[email protected]d65cab7a2008-08-12 01:25:4144 // Whether we allow sending messages with no time-out.
45 void set_sync_messages_with_no_timeout_allowed(bool value) {
46 sync_messages_with_no_timeout_allowed_ = value;
47 }
48
initial.commit09911bf2008-07-26 23:55:2949 protected:
50 class ReceivedSyncMsgQueue;
51 friend class ReceivedSyncMsgQueue;
52
53 // SyncContext holds the per object data for SyncChannel, so that SyncChannel
54 // can be deleted while it's being used in a different thread. See
55 // ChannelProxy::Context for more information.
[email protected]3cdb7af812008-10-24 19:21:1356 class SyncContext : public Context,
[email protected]1c4947f2009-01-15 22:25:1157 public base::WaitableEventWatcher::Delegate {
initial.commit09911bf2008-07-26 23:55:2958 public:
59 SyncContext(Channel::Listener* listener,
60 MessageFilter* filter,
[email protected]3cdb7af812008-10-24 19:21:1361 MessageLoop* ipc_thread,
[email protected]1c4947f2009-01-15 22:25:1162 base::WaitableEvent* shutdown_event);
initial.commit09911bf2008-07-26 23:55:2963
initial.commit09911bf2008-07-26 23:55:2964 // Adds information about an outgoing sync message to the context so that
[email protected]3cdb7af812008-10-24 19:21:1365 // we know how to deserialize the reply.
66 void Push(IPC::SyncMessage* sync_msg);
initial.commit09911bf2008-07-26 23:55:2967
[email protected]3cdb7af812008-10-24 19:21:1368 // Cleanly remove the top deserializer (and throw it away). Returns the
69 // result of the Send call for that message.
70 bool Pop();
71
72 // Returns an event that's set when the send is complete, timed out or the
73 // process shut down.
[email protected]1c4947f2009-01-15 22:25:1174 base::WaitableEvent* GetSendDoneEvent();
initial.commit09911bf2008-07-26 23:55:2975
76 // Returns an event that's set when an incoming message that's not the reply
77 // needs to get dispatched (by calling SyncContext::DispatchMessages).
[email protected]1c4947f2009-01-15 22:25:1178 base::WaitableEvent* GetDispatchEvent();
initial.commit09911bf2008-07-26 23:55:2979
80 void DispatchMessages();
initial.commit09911bf2008-07-26 23:55:2981
82 // Checks if the given message is blocking the listener thread because of a
[email protected]d3216442009-03-05 21:07:2783 // synchronous send. If it is, the thread is unblocked and true is
84 // returned. Otherwise the function returns false.
[email protected]3cdb7af812008-10-24 19:21:1385 bool TryToUnblockListener(const Message* msg);
initial.commit09911bf2008-07-26 23:55:2986
[email protected]3cdb7af812008-10-24 19:21:1387 // Called on the IPC thread when a sync send that runs a nested message loop
88 // times out.
89 void OnSendTimeout(int message_id);
90
[email protected]1c4947f2009-01-15 22:25:1191 base::WaitableEvent* shutdown_event() { return shutdown_event_; }
[email protected]d65cab7a2008-08-12 01:25:4192
[email protected]ac0efda2009-10-14 16:22:0293 ReceivedSyncMsgQueue* received_sync_msgs() {
94 return received_sync_msgs_;
95 }
96
initial.commit09911bf2008-07-26 23:55:2997 private:
[email protected]877d55d2009-11-05 21:53:0898 ~SyncContext();
[email protected]3cdb7af812008-10-24 19:21:1399 // IPC::ChannelProxy methods that we override.
100
101 // Called on the listener thread.
[email protected]877d55d2009-11-05 21:53:08102 virtual void Clear();
[email protected]3cdb7af812008-10-24 19:21:13103
104 // Called on the IPC thread.
105 virtual void OnMessageReceived(const Message& msg);
106 virtual void OnChannelError();
107 virtual void OnChannelOpened();
108 virtual void OnChannelClosed();
109
110 // Cancels all pending Send calls.
111 void CancelPendingSends();
112
[email protected]1c4947f2009-01-15 22:25:11113 // WaitableEventWatcher::Delegate implementation.
114 virtual void OnWaitableEventSignaled(base::WaitableEvent* arg);
initial.commit09911bf2008-07-26 23:55:29115
[email protected]d3216442009-03-05 21:07:27116 // When sending a synchronous message, this structure contains an object
117 // that knows how to deserialize the response.
initial.commit09911bf2008-07-26 23:55:29118 struct PendingSyncMsg {
[email protected]1c4947f2009-01-15 22:25:11119 PendingSyncMsg(int id, IPC::MessageReplyDeserializer* d,
120 base::WaitableEvent* e) :
[email protected]3cdb7af812008-10-24 19:21:13121 id(id), deserializer(d), done_event(e), send_result(false) { }
initial.commit09911bf2008-07-26 23:55:29122 int id;
123 IPC::MessageReplyDeserializer* deserializer;
[email protected]1c4947f2009-01-15 22:25:11124 base::WaitableEvent* done_event;
[email protected]3cdb7af812008-10-24 19:21:13125 bool send_result;
initial.commit09911bf2008-07-26 23:55:29126 };
127
[email protected]3cdb7af812008-10-24 19:21:13128 typedef std::deque<PendingSyncMsg> PendingSyncMessageQueue;
initial.commit09911bf2008-07-26 23:55:29129 PendingSyncMessageQueue deserializers_;
130 Lock deserializers_lock_;
131
[email protected]3cdb7af812008-10-24 19:21:13132 scoped_refptr<ReceivedSyncMsgQueue> received_sync_msgs_;
initial.commit09911bf2008-07-26 23:55:29133
[email protected]1c4947f2009-01-15 22:25:11134 base::WaitableEvent* shutdown_event_;
135 base::WaitableEventWatcher shutdown_watcher_;
initial.commit09911bf2008-07-26 23:55:29136 };
137
138 private:
[email protected]1c4947f2009-01-15 22:25:11139 // WaitableEventWatcher::Delegate implementation.
140 virtual void OnWaitableEventSignaled(base::WaitableEvent* arg);
[email protected]3cdb7af812008-10-24 19:21:13141
[email protected]d3216442009-03-05 21:07:27142 SyncContext* sync_context() {
143 return reinterpret_cast<SyncContext*>(context());
144 }
initial.commit09911bf2008-07-26 23:55:29145
[email protected]3cdb7af812008-10-24 19:21:13146 // Both these functions wait for a reply, timeout or process shutdown. The
147 // latter one also runs a nested message loop in the meantime.
[email protected]9eec2252009-12-01 02:34:18148 static void WaitForReply(
149 SyncContext* context, base::WaitableEvent* pump_messages_event);
initial.commit09911bf2008-07-26 23:55:29150
[email protected]3cdb7af812008-10-24 19:21:13151 // Runs a nested message loop until a reply arrives, times out, or the process
152 // shuts down.
[email protected]9eec2252009-12-01 02:34:18153 static void WaitForReplyWithNestedMessageLoop(SyncContext* context);
initial.commit09911bf2008-07-26 23:55:29154
[email protected]d65cab7a2008-08-12 01:25:41155 bool sync_messages_with_no_timeout_allowed_;
156
[email protected]3cdb7af812008-10-24 19:21:13157 // Used to signal events between the IPC and listener threads.
[email protected]1c4947f2009-01-15 22:25:11158 base::WaitableEventWatcher dispatch_watcher_;
[email protected]3cdb7af812008-10-24 19:21:13159
[email protected]5a3b9142009-08-28 21:03:17160 DISALLOW_EVIL_CONSTRUCTORS(SyncChannel);
initial.commit09911bf2008-07-26 23:55:29161};
162
163} // namespace IPC
164
[email protected]5a3b9142009-08-28 21:03:17165#endif // IPC_IPC_SYNC_SENDER_H__