OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_resize_helper.h" | 5 #include "content/browser/renderer_host/render_widget_resize_helper.h" |
6 | 6 |
7 #include "content/browser/gpu/gpu_process_host_ui_shim.h" | 7 #include "content/browser/gpu/gpu_process_host_ui_shim.h" |
8 #include "content/browser/renderer_host/render_process_host_impl.h" | 8 #include "content/browser/renderer_host/render_process_host_impl.h" |
9 #include "content/public/browser/browser_thread.h" | 9 #include "content/public/browser/browser_thread.h" |
10 | 10 |
(...skipping 16 matching lines...) Expand all Loading... |
27 EnqueuedTask(Type type, int process_id, const IPC::Message& m); | 27 EnqueuedTask(Type type, int process_id, const IPC::Message& m); |
28 ~EnqueuedTask(); | 28 ~EnqueuedTask(); |
29 void Run(); | 29 void Run(); |
30 void InvalidateHelper(); | 30 void InvalidateHelper(); |
31 | 31 |
32 private: | 32 private: |
33 Type type_; | 33 Type type_; |
34 int process_id_; | 34 int process_id_; |
35 IPC::Message message_; | 35 IPC::Message message_; |
36 bool has_run_; | 36 bool has_run_; |
| 37 |
| 38 // Back-pointer to the ResizeHelper which has this task in its queue. Set |
| 39 // to NULL when this task is removed from the queue. |
37 RenderWidgetResizeHelper* helper_; | 40 RenderWidgetResizeHelper* helper_; |
38 | 41 |
39 DISALLOW_COPY_AND_ASSIGN(EnqueuedTask); | 42 DISALLOW_COPY_AND_ASSIGN(EnqueuedTask); |
40 }; | 43 }; |
41 | 44 |
42 RenderWidgetResizeHelper::EnqueuedTask::EnqueuedTask( | 45 RenderWidgetResizeHelper::EnqueuedTask::EnqueuedTask( |
43 Type type, | 46 Type type, |
44 int process_id, | 47 int process_id, |
45 const IPC::Message& m) | 48 const IPC::Message& m) |
46 : type_(type), | 49 : type_(type), |
47 process_id_(process_id), | 50 process_id_(process_id), |
48 message_(m), | 51 message_(m), |
49 has_run_(false), | 52 has_run_(false), |
50 helper_(RenderWidgetResizeHelper::Get()) { | 53 helper_(RenderWidgetResizeHelper::Get()) { |
51 } | 54 } |
52 | 55 |
53 RenderWidgetResizeHelper::EnqueuedTask::~EnqueuedTask() { | 56 RenderWidgetResizeHelper::EnqueuedTask::~EnqueuedTask() { |
| 57 // Note that if the MessageLoop into which this task was posted is destroyed |
| 58 // before the RenderWidgetResizeHelper, then the helper's list of tasks will |
| 59 // point to freed data. Avoid this by removing tasks when they are freed, if |
| 60 // they weren't already removed when they were run. |
| 61 if (helper_) |
| 62 helper_->RemoveEnqueuedTaskFromQueue(this); |
54 } | 63 } |
55 | 64 |
56 void RenderWidgetResizeHelper::EnqueuedTask::Run() { | 65 void RenderWidgetResizeHelper::EnqueuedTask::Run() { |
57 if (has_run_) | 66 if (has_run_) |
58 return; | 67 return; |
59 | 68 |
60 if (helper_) | 69 if (helper_) |
61 helper_->WillRunEnqueuedTask(this); | 70 helper_->RemoveEnqueuedTaskFromQueue(this); |
62 has_run_ = true; | 71 has_run_ = true; |
63 | 72 |
64 switch (type_) { | 73 switch (type_) { |
65 case RENDERER_IPC: { | 74 case RENDERER_IPC: { |
66 RenderProcessHost* host = RenderProcessHost::FromID(process_id_); | 75 RenderProcessHost* host = RenderProcessHost::FromID(process_id_); |
67 if (host) | 76 if (host) |
68 host->OnMessageReceived(message_); | 77 host->OnMessageReceived(message_); |
69 break; | 78 break; |
70 } | 79 } |
71 case GPU_IPC: { | 80 case GPU_IPC: { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 | 135 |
127 // Notify anyone waiting on the UI thread that there is a new entry in the | 136 // Notify anyone waiting on the UI thread that there is a new entry in the |
128 // task map. If they don't find the entry they are looking for, then they | 137 // task map. If they don't find the entry they are looking for, then they |
129 // will just continue waiting. | 138 // will just continue waiting. |
130 event_.Signal(); | 139 event_.Signal(); |
131 | 140 |
132 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 141 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
133 base::Bind(&EnqueuedTask::Run, base::Owned(task))); | 142 base::Bind(&EnqueuedTask::Run, base::Owned(task))); |
134 } | 143 } |
135 | 144 |
136 void RenderWidgetResizeHelper::WillRunEnqueuedTask(EnqueuedTask* task) { | 145 void RenderWidgetResizeHelper::RemoveEnqueuedTaskFromQueue(EnqueuedTask* task) { |
137 base::AutoLock lock(task_queue_lock_); | 146 base::AutoLock lock(task_queue_lock_); |
138 DCHECK(task_queue_.front() == task); | 147 DCHECK(task_queue_.front() == task); |
139 task_queue_.pop_front(); | 148 task_queue_.pop_front(); |
| 149 task->InvalidateHelper(); |
140 } | 150 } |
141 | 151 |
142 void RenderWidgetResizeHelper::PostRendererProcessMsg( | 152 void RenderWidgetResizeHelper::PostRendererProcessMsg( |
143 int render_process_id, const IPC::Message& msg) { | 153 int render_process_id, const IPC::Message& msg) { |
144 PostEnqueuedTask(new EnqueuedTask( | 154 PostEnqueuedTask(new EnqueuedTask( |
145 EnqueuedTask::RENDERER_IPC, render_process_id, msg)); | 155 EnqueuedTask::RENDERER_IPC, render_process_id, msg)); |
146 } | 156 } |
147 | 157 |
148 void RenderWidgetResizeHelper::PostGpuProcessMsg( | 158 void RenderWidgetResizeHelper::PostGpuProcessMsg( |
149 int gpu_host_id, const IPC::Message& msg) { | 159 int gpu_host_id, const IPC::Message& msg) { |
150 PostEnqueuedTask(new EnqueuedTask(EnqueuedTask::GPU_IPC, gpu_host_id, msg)); | 160 PostEnqueuedTask(new EnqueuedTask(EnqueuedTask::GPU_IPC, gpu_host_id, msg)); |
151 } | 161 } |
152 | 162 |
153 RenderWidgetResizeHelper::RenderWidgetResizeHelper() | 163 RenderWidgetResizeHelper::RenderWidgetResizeHelper() |
154 : event_(false /* auto-reset */, false /* initially signalled */) {} | 164 : event_(false /* auto-reset */, false /* initially signalled */) {} |
155 | 165 |
156 RenderWidgetResizeHelper::~RenderWidgetResizeHelper() { | 166 RenderWidgetResizeHelper::~RenderWidgetResizeHelper() { |
157 // Ensure that any tasks that outlive this do not reach back into it. | 167 // Ensure that any tasks that outlive this do not reach back into it. |
158 for (EnqueuedTaskQueue::iterator it = task_queue_.begin(); | 168 for (EnqueuedTaskQueue::iterator it = task_queue_.begin(); |
159 it != task_queue_.end(); ++it) { | 169 it != task_queue_.end(); ++it) { |
160 EnqueuedTask* task = *it; | 170 EnqueuedTask* task = *it; |
161 task->InvalidateHelper(); | 171 task->InvalidateHelper(); |
162 } | 172 } |
163 } | 173 } |
164 | 174 |
165 } // namespace content | 175 } // namespace content |
166 | 176 |
OLD | NEW |