blob: 22e69c5409d2e3d7090105f802d6a57879828bef [file] [log] [blame]
[email protected]73a797fb2010-06-07 02:10:181// Copyright (c) 2010 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"
[email protected]1e9499c2010-04-06 20:33:3616#include "ipc/ipc_sync_message.h"
initial.commit09911bf2008-07-26 23:55:2917
[email protected]7bf730952009-05-29 09:31:1518namespace base {
19class WaitableEvent;
20};
21
initial.commit09911bf2008-07-26 23:55:2922namespace IPC {
23
24class SyncMessage;
[email protected]1c4947f2009-01-15 22:25:1125class MessageReplyDeserializer;
initial.commit09911bf2008-07-26 23:55:2926
[email protected]1e9499c2010-04-06 20:33:3627// This is similar to ChannelProxy, with the added feature of supporting sending
28// synchronous messages.
initial.commit09911bf2008-07-26 23:55:2929// Note that care must be taken that the lifetime of the ipc_thread argument
30// is more than this object. If the message loop goes away while this object
31// is running and it's used to send a message, then it will use the invalid
32// message loop pointer to proxy it to the ipc thread.
[email protected]3cdb7af812008-10-24 19:21:1333class SyncChannel : public ChannelProxy,
[email protected]1c4947f2009-01-15 22:25:1134 public base::WaitableEventWatcher::Delegate {
initial.commit09911bf2008-07-26 23:55:2935 public:
[email protected]9a3a293b2009-06-04 22:28:1636 SyncChannel(const std::string& channel_id, Channel::Mode mode,
[email protected]d65cab7a2008-08-12 01:25:4137 Channel::Listener* listener, MessageFilter* filter,
38 MessageLoop* ipc_message_loop, bool create_pipe_now,
[email protected]1c4947f2009-01-15 22:25:1139 base::WaitableEvent* shutdown_event);
[email protected]17acbb52009-08-28 17:29:0340 virtual ~SyncChannel();
initial.commit09911bf2008-07-26 23:55:2941
42 virtual bool Send(Message* message);
[email protected]d65cab7a2008-08-12 01:25:4143 virtual bool SendWithTimeout(Message* message, int timeout_ms);
initial.commit09911bf2008-07-26 23:55:2944
[email protected]d65cab7a2008-08-12 01:25:4145 // Whether we allow sending messages with no time-out.
46 void set_sync_messages_with_no_timeout_allowed(bool value) {
47 sync_messages_with_no_timeout_allowed_ = value;
48 }
49
initial.commit09911bf2008-07-26 23:55:2950 protected:
51 class ReceivedSyncMsgQueue;
52 friend class ReceivedSyncMsgQueue;
53
54 // SyncContext holds the per object data for SyncChannel, so that SyncChannel
55 // can be deleted while it's being used in a different thread. See
56 // ChannelProxy::Context for more information.
[email protected]3cdb7af812008-10-24 19:21:1357 class SyncContext : public Context,
[email protected]1c4947f2009-01-15 22:25:1158 public base::WaitableEventWatcher::Delegate {
initial.commit09911bf2008-07-26 23:55:2959 public:
60 SyncContext(Channel::Listener* listener,
61 MessageFilter* filter,
[email protected]3cdb7af812008-10-24 19:21:1362 MessageLoop* ipc_thread,
[email protected]1c4947f2009-01-15 22:25:1163 base::WaitableEvent* shutdown_event);
initial.commit09911bf2008-07-26 23:55:2964
initial.commit09911bf2008-07-26 23:55:2965 // Adds information about an outgoing sync message to the context so that
[email protected]3cdb7af812008-10-24 19:21:1366 // we know how to deserialize the reply.
[email protected]1e9499c2010-04-06 20:33:3667 void Push(SyncMessage* sync_msg);
initial.commit09911bf2008-07-26 23:55:2968
[email protected]3cdb7af812008-10-24 19:21:1369 // Cleanly remove the top deserializer (and throw it away). Returns the
70 // result of the Send call for that message.
71 bool Pop();
72
73 // Returns an event that's set when the send is complete, timed out or the
74 // process shut down.
[email protected]1c4947f2009-01-15 22:25:1175 base::WaitableEvent* GetSendDoneEvent();
initial.commit09911bf2008-07-26 23:55:2976
77 // Returns an event that's set when an incoming message that's not the reply
78 // needs to get dispatched (by calling SyncContext::DispatchMessages).
[email protected]1c4947f2009-01-15 22:25:1179 base::WaitableEvent* GetDispatchEvent();
initial.commit09911bf2008-07-26 23:55:2980
81 void DispatchMessages();
initial.commit09911bf2008-07-26 23:55:2982
83 // Checks if the given message is blocking the listener thread because of a
[email protected]d3216442009-03-05 21:07:2784 // synchronous send. If it is, the thread is unblocked and true is
85 // returned. Otherwise the function returns false.
[email protected]3cdb7af812008-10-24 19:21:1386 bool TryToUnblockListener(const Message* msg);
initial.commit09911bf2008-07-26 23:55:2987
[email protected]3cdb7af812008-10-24 19:21:1388 // Called on the IPC thread when a sync send that runs a nested message loop
89 // times out.
90 void OnSendTimeout(int message_id);
91
[email protected]1c4947f2009-01-15 22:25:1192 base::WaitableEvent* shutdown_event() { return shutdown_event_; }
[email protected]d65cab7a2008-08-12 01:25:4193
[email protected]ac0efda2009-10-14 16:22:0294 ReceivedSyncMsgQueue* received_sync_msgs() {
95 return received_sync_msgs_;
96 }
97
initial.commit09911bf2008-07-26 23:55:2998 private:
[email protected]877d55d2009-11-05 21:53:0899 ~SyncContext();
[email protected]1e9499c2010-04-06 20:33:36100 // ChannelProxy methods that we override.
[email protected]3cdb7af812008-10-24 19:21:13101
102 // Called on the listener thread.
[email protected]877d55d2009-11-05 21:53:08103 virtual void Clear();
[email protected]3cdb7af812008-10-24 19:21:13104
105 // Called on the IPC thread.
106 virtual void OnMessageReceived(const Message& msg);
107 virtual void OnChannelError();
108 virtual void OnChannelOpened();
109 virtual void OnChannelClosed();
110
111 // Cancels all pending Send calls.
112 void CancelPendingSends();
113
[email protected]1c4947f2009-01-15 22:25:11114 // WaitableEventWatcher::Delegate implementation.
115 virtual void OnWaitableEventSignaled(base::WaitableEvent* arg);
initial.commit09911bf2008-07-26 23:55:29116
[email protected]3cdb7af812008-10-24 19:21:13117 typedef std::deque<PendingSyncMsg> PendingSyncMessageQueue;
initial.commit09911bf2008-07-26 23:55:29118 PendingSyncMessageQueue deserializers_;
119 Lock deserializers_lock_;
120
[email protected]3cdb7af812008-10-24 19:21:13121 scoped_refptr<ReceivedSyncMsgQueue> received_sync_msgs_;
initial.commit09911bf2008-07-26 23:55:29122
[email protected]1c4947f2009-01-15 22:25:11123 base::WaitableEvent* shutdown_event_;
124 base::WaitableEventWatcher shutdown_watcher_;
initial.commit09911bf2008-07-26 23:55:29125 };
126
127 private:
[email protected]1c4947f2009-01-15 22:25:11128 // WaitableEventWatcher::Delegate implementation.
129 virtual void OnWaitableEventSignaled(base::WaitableEvent* arg);
[email protected]3cdb7af812008-10-24 19:21:13130
[email protected]d3216442009-03-05 21:07:27131 SyncContext* sync_context() {
132 return reinterpret_cast<SyncContext*>(context());
133 }
initial.commit09911bf2008-07-26 23:55:29134
[email protected]3cdb7af812008-10-24 19:21:13135 // Both these functions wait for a reply, timeout or process shutdown. The
136 // latter one also runs a nested message loop in the meantime.
[email protected]9eec2252009-12-01 02:34:18137 static void WaitForReply(
138 SyncContext* context, base::WaitableEvent* pump_messages_event);
initial.commit09911bf2008-07-26 23:55:29139
[email protected]3cdb7af812008-10-24 19:21:13140 // Runs a nested message loop until a reply arrives, times out, or the process
141 // shuts down.
[email protected]9eec2252009-12-01 02:34:18142 static void WaitForReplyWithNestedMessageLoop(SyncContext* context);
initial.commit09911bf2008-07-26 23:55:29143
[email protected]d65cab7a2008-08-12 01:25:41144 bool sync_messages_with_no_timeout_allowed_;
145
[email protected]3cdb7af812008-10-24 19:21:13146 // Used to signal events between the IPC and listener threads.
[email protected]1c4947f2009-01-15 22:25:11147 base::WaitableEventWatcher dispatch_watcher_;
[email protected]3cdb7af812008-10-24 19:21:13148
[email protected]73a797fb2010-06-07 02:10:18149 DISALLOW_COPY_AND_ASSIGN(SyncChannel);
initial.commit09911bf2008-07-26 23:55:29150};
151
152} // namespace IPC
153
[email protected]5a3b9142009-08-28 21:03:17154#endif // IPC_IPC_SYNC_SENDER_H__