blob: f5d2addec8f7ad2948d2b6aa15196355db55905c [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// 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.
initial.commit09911bf2008-07-26 23:55:294
[email protected]946d1b22009-07-22 23:57:215#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);
initial.commit09911bf2008-07-26 23:55:2939 ~SyncChannel();
40
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
64 ~SyncContext();
65
66 // Adds information about an outgoing sync message to the context so that
[email protected]3cdb7af812008-10-24 19:21:1367 // we know how to deserialize the reply.
68 void Push(IPC::SyncMessage* sync_msg);
initial.commit09911bf2008-07-26 23:55:2969
[email protected]3cdb7af812008-10-24 19:21:1370 // Cleanly remove the top deserializer (and throw it away). Returns the
71 // result of the Send call for that message.
72 bool Pop();
73
74 // Returns an event that's set when the send is complete, timed out or the
75 // process shut down.
[email protected]1c4947f2009-01-15 22:25:1176 base::WaitableEvent* GetSendDoneEvent();
initial.commit09911bf2008-07-26 23:55:2977
78 // Returns an event that's set when an incoming message that's not the reply
79 // needs to get dispatched (by calling SyncContext::DispatchMessages).
[email protected]1c4947f2009-01-15 22:25:1180 base::WaitableEvent* GetDispatchEvent();
initial.commit09911bf2008-07-26 23:55:2981
82 void DispatchMessages();
initial.commit09911bf2008-07-26 23:55:2983
84 // Checks if the given message is blocking the listener thread because of a
[email protected]d3216442009-03-05 21:07:2785 // synchronous send. If it is, the thread is unblocked and true is
86 // returned. Otherwise the function returns false.
[email protected]3cdb7af812008-10-24 19:21:1387 bool TryToUnblockListener(const Message* msg);
initial.commit09911bf2008-07-26 23:55:2988
[email protected]3cdb7af812008-10-24 19:21:1389 // Called on the IPC thread when a sync send that runs a nested message loop
90 // times out.
91 void OnSendTimeout(int message_id);
92
[email protected]1c4947f2009-01-15 22:25:1193 base::WaitableEvent* shutdown_event() { return shutdown_event_; }
[email protected]d65cab7a2008-08-12 01:25:4194
initial.commit09911bf2008-07-26 23:55:2995 private:
[email protected]3cdb7af812008-10-24 19:21:1396 // IPC::ChannelProxy methods that we override.
97
98 // Called on the listener thread.
99 virtual void Clear();
100
101 // Called on the IPC thread.
102 virtual void OnMessageReceived(const Message& msg);
103 virtual void OnChannelError();
104 virtual void OnChannelOpened();
105 virtual void OnChannelClosed();
106
107 // Cancels all pending Send calls.
108 void CancelPendingSends();
109
[email protected]1c4947f2009-01-15 22:25:11110 // WaitableEventWatcher::Delegate implementation.
111 virtual void OnWaitableEventSignaled(base::WaitableEvent* arg);
initial.commit09911bf2008-07-26 23:55:29112
[email protected]d3216442009-03-05 21:07:27113 // When sending a synchronous message, this structure contains an object
114 // that knows how to deserialize the response.
initial.commit09911bf2008-07-26 23:55:29115 struct PendingSyncMsg {
[email protected]1c4947f2009-01-15 22:25:11116 PendingSyncMsg(int id, IPC::MessageReplyDeserializer* d,
117 base::WaitableEvent* e) :
[email protected]3cdb7af812008-10-24 19:21:13118 id(id), deserializer(d), done_event(e), send_result(false) { }
initial.commit09911bf2008-07-26 23:55:29119 int id;
120 IPC::MessageReplyDeserializer* deserializer;
[email protected]1c4947f2009-01-15 22:25:11121 base::WaitableEvent* done_event;
[email protected]3cdb7af812008-10-24 19:21:13122 bool send_result;
initial.commit09911bf2008-07-26 23:55:29123 };
124
[email protected]3cdb7af812008-10-24 19:21:13125 typedef std::deque<PendingSyncMsg> PendingSyncMessageQueue;
initial.commit09911bf2008-07-26 23:55:29126 PendingSyncMessageQueue deserializers_;
127 Lock deserializers_lock_;
128
[email protected]3cdb7af812008-10-24 19:21:13129 scoped_refptr<ReceivedSyncMsgQueue> received_sync_msgs_;
initial.commit09911bf2008-07-26 23:55:29130
[email protected]1c4947f2009-01-15 22:25:11131 base::WaitableEvent* shutdown_event_;
132 base::WaitableEventWatcher shutdown_watcher_;
initial.commit09911bf2008-07-26 23:55:29133 };
134
135 private:
[email protected]1c4947f2009-01-15 22:25:11136 // WaitableEventWatcher::Delegate implementation.
137 virtual void OnWaitableEventSignaled(base::WaitableEvent* arg);
[email protected]3cdb7af812008-10-24 19:21:13138
[email protected]d3216442009-03-05 21:07:27139 SyncContext* sync_context() {
140 return reinterpret_cast<SyncContext*>(context());
141 }
initial.commit09911bf2008-07-26 23:55:29142
[email protected]3cdb7af812008-10-24 19:21:13143 // Both these functions wait for a reply, timeout or process shutdown. The
144 // latter one also runs a nested message loop in the meantime.
[email protected]1c4947f2009-01-15 22:25:11145 void WaitForReply(base::WaitableEvent* pump_messages_event);
initial.commit09911bf2008-07-26 23:55:29146
[email protected]3cdb7af812008-10-24 19:21:13147 // Runs a nested message loop until a reply arrives, times out, or the process
148 // shuts down.
149 void WaitForReplyWithNestedMessageLoop();
initial.commit09911bf2008-07-26 23:55:29150
[email protected]d65cab7a2008-08-12 01:25:41151 bool sync_messages_with_no_timeout_allowed_;
152
[email protected]3cdb7af812008-10-24 19:21:13153 // Used to signal events between the IPC and listener threads.
[email protected]1c4947f2009-01-15 22:25:11154 base::WaitableEventWatcher send_done_watcher_;
155 base::WaitableEventWatcher dispatch_watcher_;
[email protected]3cdb7af812008-10-24 19:21:13156
initial.commit09911bf2008-07-26 23:55:29157 DISALLOW_EVIL_CONSTRUCTORS(SyncChannel);
158};
159
160} // namespace IPC
161
[email protected]946d1b22009-07-22 23:57:21162#endif // IPC_IPC_SYNC_SENDER_H__