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

Side by Side Diff: content/browser/renderer_host/render_widget_resize_helper.cc

Issue 396483003: Separate ResizeHelper from RenderWidgetHelper (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Make dtor order more robust Created 6 years, 5 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "content/browser/renderer_host/render_widget_resize_helper.h"
6
7 #include "content/browser/gpu/gpu_process_host_ui_shim.h"
8 #include "content/browser/renderer_host/render_process_host_impl.h"
9 #include "content/public/browser/browser_thread.h"
10
11 namespace content {
12 namespace {
13 base::LazyInstance<RenderWidgetResizeHelper> g_render_widget_task_runner =
14 LAZY_INSTANCE_INITIALIZER;
15 } // namespace
16
17 // A wrapper for IPCs and tasks that we may potentially execute in
18 // WaitForSingleTaskToRun. Because these tasks are sent to two places to run,
19 // we to wrap them in this structure and track whether or not they have run
20 // yet, to avoid running them twice.
21 class RenderWidgetResizeHelper::EnqueuedTask {
22 public:
23 enum Type {
24 RENDERER_IPC,
25 GPU_IPC,
26 };
27 EnqueuedTask(Type type, int process_id, const IPC::Message& m);
28 ~EnqueuedTask();
29 void Run();
30 void InvalidateHelper();
31
32 private:
33 Type type_;
34 int process_id_;
35 IPC::Message message_;
36 bool has_run_;
37 RenderWidgetResizeHelper* helper_;
38
39 DISALLOW_COPY_AND_ASSIGN(EnqueuedTask);
40 };
41
42 RenderWidgetResizeHelper::EnqueuedTask::EnqueuedTask(
43 Type type,
44 int process_id,
45 const IPC::Message& m)
46 : type_(type),
47 process_id_(process_id),
48 message_(m),
49 has_run_(false),
50 helper_(RenderWidgetResizeHelper::Get()) {
51 }
52
53 RenderWidgetResizeHelper::EnqueuedTask::~EnqueuedTask() {
54 }
55
56 void RenderWidgetResizeHelper::EnqueuedTask::Run() {
57 if (has_run_)
58 return;
59
60 if (helper_)
61 helper_->WillRunEnqueuedTask(this);
62 has_run_ = true;
63
64 switch (type_) {
65 case RENDERER_IPC: {
66 RenderProcessHost* host = RenderProcessHost::FromID(process_id_);
67 if (host)
68 host->OnMessageReceived(message_);
69 break;
70 }
71 case GPU_IPC: {
72 GpuProcessHostUIShim* host = GpuProcessHostUIShim::FromID(process_id_);
73 if (host)
74 host->OnMessageReceived(message_);
75 break;
76 }
77 }
78 }
79
80 void RenderWidgetResizeHelper::EnqueuedTask::InvalidateHelper() {
81 helper_ = NULL;
82 }
83
84 // static
85 RenderWidgetResizeHelper* RenderWidgetResizeHelper::Get() {
86 return g_render_widget_task_runner.Pointer();
87 }
88
89 bool RenderWidgetResizeHelper::WaitForSingleTaskToRun(
90 const base::TimeDelta& max_delay) {
91 base::TimeTicks time_start = base::TimeTicks::Now();
92
93 for (;;) {
94 // Peek at the message from the front of the queue. Running it will remove
95 // it from the queue.
96 EnqueuedTask* task = NULL;
97 {
98 base::AutoLock lock(task_queue_lock_);
99 if (!task_queue_.empty())
100 task = task_queue_.front();
101 }
102
103 if (task) {
104 task->Run();
105 return true;
106 }
107
108 // Calculate the maximum amount of time that we are willing to sleep.
109 base::TimeDelta max_sleep_time =
110 max_delay - (base::TimeTicks::Now() - time_start);
111 if (max_sleep_time <= base::TimeDelta::FromMilliseconds(0))
112 break;
113
114 base::ThreadRestrictions::ScopedAllowWait allow_wait;
115 event_.TimedWait(max_sleep_time);
116 }
117
118 return false;
119 }
120
121 void RenderWidgetResizeHelper::PostEnqueuedTask(EnqueuedTask* task) {
122 {
123 base::AutoLock lock(task_queue_lock_);
124 task_queue_.push_back(task);
125 }
126
127 // 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
129 // will just continue waiting.
130 event_.Signal();
131
132 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
133 base::Bind(&EnqueuedTask::Run, base::Owned(task)));
134 }
135
136 void RenderWidgetResizeHelper::WillRunEnqueuedTask(EnqueuedTask* task) {
137 base::AutoLock lock(task_queue_lock_);
138 DCHECK(task_queue_.front() == task);
139 task_queue_.pop_front();
140 }
141
142 void RenderWidgetResizeHelper::PostRendererProcessMsg(
143 int render_process_id, const IPC::Message& msg) {
144 PostEnqueuedTask(new EnqueuedTask(
145 EnqueuedTask::RENDERER_IPC, render_process_id, msg));
146 }
147
148 void RenderWidgetResizeHelper::PostGpuProcessMsg(
149 int gpu_host_id, const IPC::Message& msg) {
150 PostEnqueuedTask(new EnqueuedTask(EnqueuedTask::GPU_IPC, gpu_host_id, msg));
151 }
152
153 RenderWidgetResizeHelper::RenderWidgetResizeHelper()
154 : event_(false /* auto-reset */, false /* initially signalled */) {}
155
156 RenderWidgetResizeHelper::~RenderWidgetResizeHelper() {
157 // Ensure that any tasks that outlive this do not reach back into it.
158 for (EnqueuedTaskQueue::iterator it = task_queue_.begin();
159 it != task_queue_.end(); ++it) {
160 EnqueuedTask* task = *it;
161 task->InvalidateHelper();
162 }
163 }
164
165 } // namespace content
166
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_widget_resize_helper.h ('k') | content/common/view_messages.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698