| 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 |