OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include "content/browser/renderer_host/render_widget_helper.h" | 5 #include "content/browser/renderer_host/render_widget_helper.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/bind_helpers.h" |
8 #include "base/eintr_wrapper.h" | 9 #include "base/eintr_wrapper.h" |
9 #include "base/threading/thread.h" | 10 #include "base/threading/thread.h" |
10 #include "content/browser/renderer_host/render_process_host_impl.h" | 11 #include "content/browser/renderer_host/render_process_host_impl.h" |
11 #include "content/browser/renderer_host/render_view_host.h" | 12 #include "content/browser/renderer_host/render_view_host.h" |
12 #include "content/browser/renderer_host/resource_dispatcher_host.h" | 13 #include "content/browser/renderer_host/resource_dispatcher_host.h" |
13 #include "content/common/view_messages.h" | 14 #include "content/common/view_messages.h" |
14 #include "content/public/browser/browser_thread.h" | 15 #include "content/public/browser/browser_thread.h" |
15 | 16 |
16 using content::BrowserThread; | 17 using content::BrowserThread; |
17 | 18 |
18 // A Task used with InvokeLater that we hold a pointer to in pending_paints_. | 19 // A helper used with DidReceiveUpdateMsg that we hold a pointer to in |
19 // Instances are deleted by MessageLoop after it calls their Run method. | 20 // pending_paints_. |
20 class RenderWidgetHelper::UpdateMsgProxy : public Task { | 21 class RenderWidgetHelper::UpdateMsgProxy { |
21 public: | 22 public: |
22 UpdateMsgProxy(RenderWidgetHelper* h, const IPC::Message& m) | 23 UpdateMsgProxy(RenderWidgetHelper* h, const IPC::Message& m); |
23 : helper(h), | 24 ~UpdateMsgProxy(); |
24 message(m), | 25 void Run(); |
25 cancelled(false) { | 26 void Cancel() { cancelled_ = true; } |
26 } | |
27 | 27 |
28 ~UpdateMsgProxy() { | 28 const IPC::Message& message() const { return message_; } |
29 // If the paint message was never dispatched, then we need to let the | |
30 // helper know that we are going away. | |
31 if (!cancelled && helper) | |
32 helper->OnDiscardUpdateMsg(this); | |
33 } | |
34 | 29 |
35 virtual void Run() { | 30 private: |
36 if (!cancelled) { | 31 scoped_refptr<RenderWidgetHelper> helper_; |
37 helper->OnDispatchUpdateMsg(this); | 32 IPC::Message message_; |
38 helper = NULL; | 33 bool cancelled_; // If true, then the message will not be dispatched. |
39 } | |
40 } | |
41 | |
42 scoped_refptr<RenderWidgetHelper> helper; | |
43 IPC::Message message; | |
44 bool cancelled; // If true, then the message will not be dispatched. | |
45 | 34 |
46 DISALLOW_COPY_AND_ASSIGN(UpdateMsgProxy); | 35 DISALLOW_COPY_AND_ASSIGN(UpdateMsgProxy); |
47 }; | 36 }; |
48 | 37 |
| 38 RenderWidgetHelper::UpdateMsgProxy::UpdateMsgProxy( |
| 39 RenderWidgetHelper* h, const IPC::Message& m) |
| 40 : helper_(h), |
| 41 message_(m), |
| 42 cancelled_(false) { |
| 43 } |
| 44 |
| 45 RenderWidgetHelper::UpdateMsgProxy::~UpdateMsgProxy() { |
| 46 // If the paint message was never dispatched, then we need to let the |
| 47 // helper know that we are going away. |
| 48 if (!cancelled_ && helper_) |
| 49 helper_->OnDiscardUpdateMsg(this); |
| 50 } |
| 51 |
| 52 void RenderWidgetHelper::UpdateMsgProxy::Run() { |
| 53 if (!cancelled_) { |
| 54 helper_->OnDispatchUpdateMsg(this); |
| 55 helper_ = NULL; |
| 56 } |
| 57 } |
| 58 |
49 RenderWidgetHelper::RenderWidgetHelper() | 59 RenderWidgetHelper::RenderWidgetHelper() |
50 : render_process_id_(-1), | 60 : render_process_id_(-1), |
51 #if defined(OS_WIN) | 61 #if defined(OS_WIN) |
52 event_(CreateEvent(NULL, FALSE /* auto-reset */, FALSE, NULL)), | 62 event_(CreateEvent(NULL, FALSE /* auto-reset */, FALSE, NULL)), |
53 #elif defined(OS_POSIX) | 63 #elif defined(OS_POSIX) |
54 event_(false /* auto-reset */, false), | 64 event_(false /* auto-reset */, false), |
55 #endif | 65 #endif |
56 resource_dispatcher_host_(NULL) { | 66 resource_dispatcher_host_(NULL) { |
57 } | 67 } |
58 | 68 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 base::AutoLock lock(pending_paints_lock_); | 118 base::AutoLock lock(pending_paints_lock_); |
109 | 119 |
110 UpdateMsgProxyMap::iterator it = pending_paints_.find(render_widget_id); | 120 UpdateMsgProxyMap::iterator it = pending_paints_.find(render_widget_id); |
111 if (it != pending_paints_.end()) { | 121 if (it != pending_paints_.end()) { |
112 UpdateMsgProxyQueue &queue = it->second; | 122 UpdateMsgProxyQueue &queue = it->second; |
113 DCHECK(!queue.empty()); | 123 DCHECK(!queue.empty()); |
114 proxy = queue.front(); | 124 proxy = queue.front(); |
115 | 125 |
116 // Flag the proxy as cancelled so that when it is run as a task it will | 126 // Flag the proxy as cancelled so that when it is run as a task it will |
117 // do nothing. | 127 // do nothing. |
118 proxy->cancelled = true; | 128 proxy->Cancel(); |
119 | 129 |
120 queue.pop_front(); | 130 queue.pop_front(); |
121 if (queue.empty()) | 131 if (queue.empty()) |
122 pending_paints_.erase(it); | 132 pending_paints_.erase(it); |
123 } | 133 } |
124 } | 134 } |
125 | 135 |
126 if (proxy) { | 136 if (proxy) { |
127 *msg = proxy->message; | 137 *msg = proxy->message(); |
128 DCHECK(msg->routing_id() == render_widget_id); | 138 DCHECK(msg->routing_id() == render_widget_id); |
129 return true; | 139 return true; |
130 } | 140 } |
131 | 141 |
132 // Calculate the maximum amount of time that we are willing to sleep. | 142 // Calculate the maximum amount of time that we are willing to sleep. |
133 base::TimeDelta max_sleep_time = | 143 base::TimeDelta max_sleep_time = |
134 max_delay - (base::TimeTicks::Now() - time_start); | 144 max_delay - (base::TimeTicks::Now() - time_start); |
135 if (max_sleep_time <= base::TimeDelta::FromMilliseconds(0)) | 145 if (max_sleep_time <= base::TimeDelta::FromMilliseconds(0)) |
136 break; | 146 break; |
137 | 147 |
(...skipping 11 matching lines...) Expand all Loading... |
149 base::AutoLock lock(pending_paints_lock_); | 159 base::AutoLock lock(pending_paints_lock_); |
150 | 160 |
151 pending_paints_[render_widget_id].push_back(proxy); | 161 pending_paints_[render_widget_id].push_back(proxy); |
152 } | 162 } |
153 | 163 |
154 // Notify anyone waiting on the UI thread that there is a new entry in the | 164 // Notify anyone waiting on the UI thread that there is a new entry in the |
155 // proxy map. If they don't find the entry they are looking for, then they | 165 // proxy map. If they don't find the entry they are looking for, then they |
156 // will just continue waiting. | 166 // will just continue waiting. |
157 event_.Signal(); | 167 event_.Signal(); |
158 | 168 |
159 // The proxy will be deleted when it is run as a task. | 169 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
160 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, proxy); | 170 base::Bind(&UpdateMsgProxy::Run, base::Owned(proxy))); |
161 } | 171 } |
162 | 172 |
163 void RenderWidgetHelper::OnDiscardUpdateMsg(UpdateMsgProxy* proxy) { | 173 void RenderWidgetHelper::OnDiscardUpdateMsg(UpdateMsgProxy* proxy) { |
164 const IPC::Message& msg = proxy->message; | 174 const IPC::Message& msg = proxy->message(); |
165 | 175 |
166 // Remove the proxy from the map now that we are going to handle it normally. | 176 // Remove the proxy from the map now that we are going to handle it normally. |
167 { | 177 { |
168 base::AutoLock lock(pending_paints_lock_); | 178 base::AutoLock lock(pending_paints_lock_); |
169 | 179 |
170 UpdateMsgProxyMap::iterator it = pending_paints_.find(msg.routing_id()); | 180 UpdateMsgProxyMap::iterator it = pending_paints_.find(msg.routing_id()); |
171 DCHECK(it != pending_paints_.end()); | 181 DCHECK(it != pending_paints_.end()); |
172 UpdateMsgProxyQueue &queue = it->second; | 182 UpdateMsgProxyQueue &queue = it->second; |
173 DCHECK(queue.front() == proxy); | 183 DCHECK(queue.front() == proxy); |
174 | 184 |
175 queue.pop_front(); | 185 queue.pop_front(); |
176 if (queue.empty()) | 186 if (queue.empty()) |
177 pending_paints_.erase(it); | 187 pending_paints_.erase(it); |
178 } | 188 } |
179 } | 189 } |
180 | 190 |
181 void RenderWidgetHelper::OnDispatchUpdateMsg(UpdateMsgProxy* proxy) { | 191 void RenderWidgetHelper::OnDispatchUpdateMsg(UpdateMsgProxy* proxy) { |
182 OnDiscardUpdateMsg(proxy); | 192 OnDiscardUpdateMsg(proxy); |
183 | 193 |
184 // It is reasonable for the host to no longer exist. | 194 // It is reasonable for the host to no longer exist. |
185 content::RenderProcessHost* host = | 195 content::RenderProcessHost* host = |
186 content::RenderProcessHost::FromID(render_process_id_); | 196 content::RenderProcessHost::FromID(render_process_id_); |
187 if (host) | 197 if (host) |
188 host->OnMessageReceived(proxy->message); | 198 host->OnMessageReceived(proxy->message()); |
189 } | 199 } |
190 | 200 |
191 void RenderWidgetHelper::OnCancelResourceRequests( | 201 void RenderWidgetHelper::OnCancelResourceRequests( |
192 int render_widget_id) { | 202 int render_widget_id) { |
193 resource_dispatcher_host_->CancelRequestsForRoute( | 203 resource_dispatcher_host_->CancelRequestsForRoute( |
194 render_process_id_, render_widget_id); | 204 render_process_id_, render_widget_id); |
195 } | 205 } |
196 | 206 |
197 void RenderWidgetHelper::OnCrossSiteSwapOutACK( | 207 void RenderWidgetHelper::OnCrossSiteSwapOutACK( |
198 const ViewMsg_SwapOut_Params& params) { | 208 const ViewMsg_SwapOut_Params& params) { |
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 gfx::PluginWindowHandle RenderWidgetHelper::LookupCompositingSurface( | 348 gfx::PluginWindowHandle RenderWidgetHelper::LookupCompositingSurface( |
339 int render_widget_id) { | 349 int render_widget_id) { |
340 base::AutoLock locked(view_compositing_surface_map_lock_); | 350 base::AutoLock locked(view_compositing_surface_map_lock_); |
341 ViewCompositingSurfaceMap::iterator it = | 351 ViewCompositingSurfaceMap::iterator it = |
342 view_compositing_surface_map_.find(render_widget_id); | 352 view_compositing_surface_map_.find(render_widget_id); |
343 if (it == view_compositing_surface_map_.end()) | 353 if (it == view_compositing_surface_map_.end()) |
344 return gfx::kNullPluginWindow; | 354 return gfx::kNullPluginWindow; |
345 | 355 |
346 return it->second; | 356 return it->second; |
347 } | 357 } |
OLD | NEW |