| OLD | NEW |
| 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 #include "chrome/browser/renderer_host/render_widget_helper.h" | 5 #include "chrome/browser/renderer_host/render_widget_helper.h" |
| 6 | 6 |
| 7 #include "base/eintr_wrapper.h" | 7 #include "base/eintr_wrapper.h" |
| 8 #include "base/thread.h" | 8 #include "base/thread.h" |
| 9 #include "chrome/browser/chrome_thread.h" | 9 #include "chrome/browser/chrome_thread.h" |
| 10 #include "chrome/browser/renderer_host/render_process_host.h" | 10 #include "chrome/browser/renderer_host/render_process_host.h" |
| 11 #include "chrome/browser/renderer_host/render_view_host.h" | 11 #include "chrome/browser/renderer_host/render_view_host.h" |
| 12 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" | 12 #include "chrome/browser/renderer_host/resource_dispatcher_host.h" |
| 13 #include "chrome/common/render_messages.h" | 13 #include "chrome/common/render_messages.h" |
| 14 | 14 |
| 15 // A Task used with InvokeLater that we hold a pointer to in pending_paints_. | 15 // A Task used with InvokeLater that we hold a pointer to in pending_paints_. |
| 16 // Instances are deleted by MessageLoop after it calls their Run method. | 16 // Instances are deleted by MessageLoop after it calls their Run method. |
| 17 class RenderWidgetHelper::UpdateMsgProxy : public Task { | 17 class RenderWidgetHelper::PaintMsgProxy : public Task { |
| 18 public: | 18 public: |
| 19 UpdateMsgProxy(RenderWidgetHelper* h, const IPC::Message& m) | 19 PaintMsgProxy(RenderWidgetHelper* h, const IPC::Message& m) |
| 20 : helper(h), | 20 : helper(h), |
| 21 message(m), | 21 message(m), |
| 22 cancelled(false) { | 22 cancelled(false) { |
| 23 } | 23 } |
| 24 | 24 |
| 25 ~UpdateMsgProxy() { | 25 ~PaintMsgProxy() { |
| 26 // If the paint message was never dispatched, then we need to let the | 26 // If the paint message was never dispatched, then we need to let the |
| 27 // helper know that we are going away. | 27 // helper know that we are going away. |
| 28 if (!cancelled && helper) | 28 if (!cancelled && helper) |
| 29 helper->OnDiscardUpdateMsg(this); | 29 helper->OnDiscardPaintMsg(this); |
| 30 } | 30 } |
| 31 | 31 |
| 32 virtual void Run() { | 32 virtual void Run() { |
| 33 if (!cancelled) { | 33 if (!cancelled) { |
| 34 helper->OnDispatchUpdateMsg(this); | 34 helper->OnDispatchPaintMsg(this); |
| 35 helper = NULL; | 35 helper = NULL; |
| 36 } | 36 } |
| 37 } | 37 } |
| 38 | 38 |
| 39 scoped_refptr<RenderWidgetHelper> helper; | 39 scoped_refptr<RenderWidgetHelper> helper; |
| 40 IPC::Message message; | 40 IPC::Message message; |
| 41 bool cancelled; // If true, then the message will not be dispatched. | 41 bool cancelled; // If true, then the message will not be dispatched. |
| 42 | 42 |
| 43 DISALLOW_COPY_AND_ASSIGN(UpdateMsgProxy); | 43 DISALLOW_COPY_AND_ASSIGN(PaintMsgProxy); |
| 44 }; | 44 }; |
| 45 | 45 |
| 46 RenderWidgetHelper::RenderWidgetHelper() | 46 RenderWidgetHelper::RenderWidgetHelper() |
| 47 : render_process_id_(-1), | 47 : render_process_id_(-1), |
| 48 #if defined(OS_WIN) | 48 #if defined(OS_WIN) |
| 49 event_(CreateEvent(NULL, FALSE /* auto-reset */, FALSE, NULL)), | 49 event_(CreateEvent(NULL, FALSE /* auto-reset */, FALSE, NULL)), |
| 50 #elif defined(OS_POSIX) | 50 #elif defined(OS_POSIX) |
| 51 event_(false /* auto-reset */, false), | 51 event_(false /* auto-reset */, false), |
| 52 #endif | 52 #endif |
| 53 resource_dispatcher_host_(NULL) { | 53 resource_dispatcher_host_(NULL) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 | 87 |
| 88 void RenderWidgetHelper::CrossSiteClosePageACK( | 88 void RenderWidgetHelper::CrossSiteClosePageACK( |
| 89 const ViewMsg_ClosePage_Params& params) { | 89 const ViewMsg_ClosePage_Params& params) { |
| 90 ChromeThread::PostTask( | 90 ChromeThread::PostTask( |
| 91 ChromeThread::IO, FROM_HERE, | 91 ChromeThread::IO, FROM_HERE, |
| 92 NewRunnableMethod(this, | 92 NewRunnableMethod(this, |
| 93 &RenderWidgetHelper::OnCrossSiteClosePageACK, | 93 &RenderWidgetHelper::OnCrossSiteClosePageACK, |
| 94 params)); | 94 params)); |
| 95 } | 95 } |
| 96 | 96 |
| 97 bool RenderWidgetHelper::WaitForUpdateMsg(int render_widget_id, | 97 bool RenderWidgetHelper::WaitForPaintMsg(int render_widget_id, |
| 98 const base::TimeDelta& max_delay, | 98 const base::TimeDelta& max_delay, |
| 99 IPC::Message* msg) { | 99 IPC::Message* msg) { |
| 100 base::TimeTicks time_start = base::TimeTicks::Now(); | 100 base::TimeTicks time_start = base::TimeTicks::Now(); |
| 101 | 101 |
| 102 for (;;) { | 102 for (;;) { |
| 103 UpdateMsgProxy* proxy = NULL; | 103 PaintMsgProxy* proxy = NULL; |
| 104 { | 104 { |
| 105 AutoLock lock(pending_paints_lock_); | 105 AutoLock lock(pending_paints_lock_); |
| 106 | 106 |
| 107 UpdateMsgProxyMap::iterator it = pending_paints_.find(render_widget_id); | 107 PaintMsgProxyMap::iterator it = pending_paints_.find(render_widget_id); |
| 108 if (it != pending_paints_.end()) { | 108 if (it != pending_paints_.end()) { |
| 109 proxy = it->second; | 109 proxy = it->second; |
| 110 | 110 |
| 111 // Flag the proxy as cancelled so that when it is run as a task it will | 111 // Flag the proxy as cancelled so that when it is run as a task it will |
| 112 // do nothing. | 112 // do nothing. |
| 113 proxy->cancelled = true; | 113 proxy->cancelled = true; |
| 114 | 114 |
| 115 pending_paints_.erase(it); | 115 pending_paints_.erase(it); |
| 116 } | 116 } |
| 117 } | 117 } |
| 118 | 118 |
| 119 if (proxy) { | 119 if (proxy) { |
| 120 *msg = proxy->message; | 120 *msg = proxy->message; |
| 121 DCHECK(msg->routing_id() == render_widget_id); | 121 DCHECK(msg->routing_id() == render_widget_id); |
| 122 return true; | 122 return true; |
| 123 } | 123 } |
| 124 | 124 |
| 125 // Calculate the maximum amount of time that we are willing to sleep. | 125 // Calculate the maximum amount of time that we are willing to sleep. |
| 126 base::TimeDelta max_sleep_time = | 126 base::TimeDelta max_sleep_time = |
| 127 max_delay - (base::TimeTicks::Now() - time_start); | 127 max_delay - (base::TimeTicks::Now() - time_start); |
| 128 if (max_sleep_time <= base::TimeDelta::FromMilliseconds(0)) | 128 if (max_sleep_time <= base::TimeDelta::FromMilliseconds(0)) |
| 129 break; | 129 break; |
| 130 | 130 |
| 131 event_.TimedWait(max_sleep_time); | 131 event_.TimedWait(max_sleep_time); |
| 132 } | 132 } |
| 133 | 133 |
| 134 return false; | 134 return false; |
| 135 } | 135 } |
| 136 | 136 |
| 137 void RenderWidgetHelper::DidReceiveUpdateMsg(const IPC::Message& msg) { | 137 void RenderWidgetHelper::DidReceivePaintMsg(const IPC::Message& msg) { |
| 138 int render_widget_id = msg.routing_id(); | 138 int render_widget_id = msg.routing_id(); |
| 139 | 139 |
| 140 UpdateMsgProxy* proxy = NULL; | 140 PaintMsgProxy* proxy = NULL; |
| 141 { | 141 { |
| 142 AutoLock lock(pending_paints_lock_); | 142 AutoLock lock(pending_paints_lock_); |
| 143 | 143 |
| 144 UpdateMsgProxyMap::value_type new_value(render_widget_id, NULL); | 144 PaintMsgProxyMap::value_type new_value(render_widget_id, NULL); |
| 145 | 145 |
| 146 // We expect only a single PaintRect message at a time. Optimize for the | 146 // We expect only a single PaintRect message at a time. Optimize for the |
| 147 // case that we don't already have an entry by using the 'insert' method. | 147 // case that we don't already have an entry by using the 'insert' method. |
| 148 std::pair<UpdateMsgProxyMap::iterator, bool> result = | 148 std::pair<PaintMsgProxyMap::iterator, bool> result = |
| 149 pending_paints_.insert(new_value); | 149 pending_paints_.insert(new_value); |
| 150 if (!result.second) { | 150 if (!result.second) { |
| 151 NOTREACHED() << "Unexpected PaintRect message!"; | 151 NOTREACHED() << "Unexpected PaintRect message!"; |
| 152 return; | 152 return; |
| 153 } | 153 } |
| 154 | 154 |
| 155 result.first->second = (proxy = new UpdateMsgProxy(this, msg)); | 155 result.first->second = (proxy = new PaintMsgProxy(this, msg)); |
| 156 } | 156 } |
| 157 | 157 |
| 158 // Notify anyone waiting on the UI thread that there is a new entry in the | 158 // Notify anyone waiting on the UI thread that there is a new entry in the |
| 159 // proxy map. If they don't find the entry they are looking for, then they | 159 // proxy map. If they don't find the entry they are looking for, then they |
| 160 // will just continue waiting. | 160 // will just continue waiting. |
| 161 event_.Signal(); | 161 event_.Signal(); |
| 162 | 162 |
| 163 // The proxy will be deleted when it is run as a task. | 163 // The proxy will be deleted when it is run as a task. |
| 164 ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, proxy); | 164 ChromeThread::PostTask(ChromeThread::UI, FROM_HERE, proxy); |
| 165 } | 165 } |
| 166 | 166 |
| 167 void RenderWidgetHelper::OnDiscardUpdateMsg(UpdateMsgProxy* proxy) { | 167 void RenderWidgetHelper::OnDiscardPaintMsg(PaintMsgProxy* proxy) { |
| 168 const IPC::Message& msg = proxy->message; | 168 const IPC::Message& msg = proxy->message; |
| 169 | 169 |
| 170 // Remove the proxy from the map now that we are going to handle it normally. | 170 // Remove the proxy from the map now that we are going to handle it normally. |
| 171 { | 171 { |
| 172 AutoLock lock(pending_paints_lock_); | 172 AutoLock lock(pending_paints_lock_); |
| 173 | 173 |
| 174 UpdateMsgProxyMap::iterator it = pending_paints_.find(msg.routing_id()); | 174 PaintMsgProxyMap::iterator it = pending_paints_.find(msg.routing_id()); |
| 175 DCHECK(it != pending_paints_.end()); | 175 DCHECK(it != pending_paints_.end()); |
| 176 DCHECK(it->second == proxy); | 176 DCHECK(it->second == proxy); |
| 177 | 177 |
| 178 pending_paints_.erase(it); | 178 pending_paints_.erase(it); |
| 179 } | 179 } |
| 180 } | 180 } |
| 181 | 181 |
| 182 void RenderWidgetHelper::OnDispatchUpdateMsg(UpdateMsgProxy* proxy) { | 182 void RenderWidgetHelper::OnDispatchPaintMsg(PaintMsgProxy* proxy) { |
| 183 OnDiscardUpdateMsg(proxy); | 183 OnDiscardPaintMsg(proxy); |
| 184 | 184 |
| 185 // It is reasonable for the host to no longer exist. | 185 // It is reasonable for the host to no longer exist. |
| 186 RenderProcessHost* host = RenderProcessHost::FromID(render_process_id_); | 186 RenderProcessHost* host = RenderProcessHost::FromID(render_process_id_); |
| 187 if (host) | 187 if (host) |
| 188 host->OnMessageReceived(proxy->message); | 188 host->OnMessageReceived(proxy->message); |
| 189 } | 189 } |
| 190 | 190 |
| 191 void RenderWidgetHelper::OnCancelResourceRequests( | 191 void RenderWidgetHelper::OnCancelResourceRequests( |
| 192 int render_widget_id) { | 192 int render_widget_id) { |
| 193 resource_dispatcher_host_->CancelRequestsForRoute( | 193 resource_dispatcher_host_->CancelRequestsForRoute( |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 295 | 295 |
| 296 void RenderWidgetHelper::ClearAllocatedDIBs() { | 296 void RenderWidgetHelper::ClearAllocatedDIBs() { |
| 297 for (std::map<TransportDIB::Id, int>::iterator | 297 for (std::map<TransportDIB::Id, int>::iterator |
| 298 i = allocated_dibs_.begin(); i != allocated_dibs_.end(); ++i) { | 298 i = allocated_dibs_.begin(); i != allocated_dibs_.end(); ++i) { |
| 299 HANDLE_EINTR(close(i->second)); | 299 HANDLE_EINTR(close(i->second)); |
| 300 } | 300 } |
| 301 | 301 |
| 302 allocated_dibs_.clear(); | 302 allocated_dibs_.clear(); |
| 303 } | 303 } |
| 304 #endif | 304 #endif |
| OLD | NEW |