Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(243)

Side by Side Diff: chrome/common/ipc_sync_channel.h

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

Powered by Google App Engine
This is Rietveld 408576698