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

Side by Side Diff: chrome/renderer/render_widget.cc

Issue 28090: Keeping track of whether WebKit is in the callstack using RenderThread doesn'... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 10 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 | Annotate | Revision Log
OLDNEW
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/renderer/render_widget.h" 5 #include "chrome/renderer/render_widget.h"
6 6
7 #include "base/gfx/point.h" 7 #include "base/gfx/point.h"
8 #include "base/gfx/size.h" 8 #include "base/gfx/size.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/message_loop.h" 10 #include "base/message_loop.h"
11 #include "base/scoped_ptr.h" 11 #include "base/scoped_ptr.h"
12 #include "build/build_config.h" 12 #include "build/build_config.h"
13 #include "chrome/common/render_messages.h" 13 #include "chrome/common/render_messages.h"
14 #include "chrome/common/transport_dib.h" 14 #include "chrome/common/transport_dib.h"
15 #include "chrome/renderer/render_process.h" 15 #include "chrome/renderer/render_process.h"
16 #include "skia/ext/platform_canvas.h" 16 #include "skia/ext/platform_canvas.h"
17 17
18 #if defined(OS_POSIX) 18 #if defined(OS_POSIX)
19 #include "skia/include/SkPixelRef.h" 19 #include "skia/include/SkPixelRef.h"
20 #include "skia/include/SkMallocPixelRef.h" 20 #include "skia/include/SkMallocPixelRef.h"
21 #endif // defined(OS_POSIX) 21 #endif // defined(OS_POSIX)
22 22
23 #include "webkit/glue/webinputevent.h" 23 #include "webkit/glue/webinputevent.h"
24 #include "webkit/glue/webwidget.h" 24 #include "webkit/glue/webwidget.h"
25 25
26 ///////////////////////////////////////////////////////////////////////////////
27
28 namespace {
29
30 // This class is used to defer calling RenderWidget::Close() while the current
31 // thread is inside RenderThread::Send(), which in some cases can result in a
32 // nested MessageLoop being run.
33 class DeferredCloses : public Task {
34 public:
35 // Called to queue a deferred close for the given widget.
36 static void Push(RenderWidget* widget) {
37 if (!current_)
38 current_ = new DeferredCloses();
39 current_->queue_.push(widget);
40 }
41
42 // Called to trigger any deferred closes to be run.
43 static void Post() {
44 if (current_) {
45 MessageLoop::current()->PostTask(FROM_HERE, current_);
46 current_ = NULL;
47 }
48 }
49
50 private:
51 virtual void Run() {
52 // Maybe we are being run from within another RenderWidget::Send call. If
53 // that is true, then we need to re-queue the widgets to be closed and try
54 // again later.
55 while (!queue_.empty()) {
56 if (queue_.front()->InSend()) {
57 Push(queue_.front());
58 } else {
59 queue_.front()->Close();
60 }
61 queue_.pop();
62 }
63 }
64
65 // The current DeferredCloses object.
66 static DeferredCloses* current_;
67
68 typedef std::queue< scoped_refptr<RenderWidget> > WidgetQueue;
69 WidgetQueue queue_;
70 };
71
72 DeferredCloses* DeferredCloses::current_ = NULL;
73
74 } // namespace
75
76 ///////////////////////////////////////////////////////////////////////////////
77
78 RenderWidget::RenderWidget(RenderThreadBase* render_thread, bool activatable) 26 RenderWidget::RenderWidget(RenderThreadBase* render_thread, bool activatable)
79 : routing_id_(MSG_ROUTING_NONE), 27 : routing_id_(MSG_ROUTING_NONE),
80 webwidget_(NULL), 28 webwidget_(NULL),
81 opener_id_(MSG_ROUTING_NONE), 29 opener_id_(MSG_ROUTING_NONE),
82 render_thread_(render_thread), 30 render_thread_(render_thread),
83 host_window_(NULL), 31 host_window_(NULL),
84 current_paint_buf_(NULL), 32 current_paint_buf_(NULL),
85 current_scroll_buf_(NULL), 33 current_scroll_buf_(NULL),
86 next_paint_flags_(0), 34 next_paint_flags_(0),
87 paint_reply_pending_(false), 35 paint_reply_pending_(false),
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 // Don't send any messages after the browser has told us to close. 126 // Don't send any messages after the browser has told us to close.
179 if (closing_) { 127 if (closing_) {
180 delete message; 128 delete message;
181 return false; 129 return false;
182 } 130 }
183 131
184 // If given a messsage without a routing ID, then assign our routing ID. 132 // If given a messsage without a routing ID, then assign our routing ID.
185 if (message->routing_id() == MSG_ROUTING_NONE) 133 if (message->routing_id() == MSG_ROUTING_NONE)
186 message->set_routing_id(routing_id_); 134 message->set_routing_id(routing_id_);
187 135
188 bool rv = render_thread_->Send(message); 136 return render_thread_->Send(message);
189
190 // If there aren't any more RenderThread::Send calls on the stack, then we
191 // can go ahead and schedule Close to be called on any RenderWidget objects
192 // that received a ViewMsg_Close while we were inside Send.
193 if (!render_thread_->InSend())
194 DeferredCloses::Post();
195
196 return rv;
197 }
198
199 bool RenderWidget::InSend() const {
200 return render_thread_->InSend();
201 } 137 }
202 138
203 // Got a response from the browser after the renderer decided to create a new 139 // Got a response from the browser after the renderer decided to create a new
204 // view. 140 // view.
205 void RenderWidget::OnCreatingNewAck(gfx::NativeViewId parent) { 141 void RenderWidget::OnCreatingNewAck(gfx::NativeViewId parent) {
206 DCHECK(routing_id_ != MSG_ROUTING_NONE); 142 DCHECK(routing_id_ != MSG_ROUTING_NONE);
207 143
208 CompleteInit(parent); 144 CompleteInit(parent);
209 } 145 }
210 146
211 void RenderWidget::OnClose() { 147 void RenderWidget::OnClose() {
212 if (closing_) 148 if (closing_)
213 return; 149 return;
214 closing_ = true; 150 closing_ = true;
215 151
216 // Browser correspondence is no longer needed at this point. 152 // Browser correspondence is no longer needed at this point.
217 if (routing_id_ != MSG_ROUTING_NONE) 153 if (routing_id_ != MSG_ROUTING_NONE)
218 render_thread_->RemoveRoute(routing_id_); 154 render_thread_->RemoveRoute(routing_id_);
219 155
220 // Balances the AddRef taken when we called AddRoute. This release happens 156 // If there is a Send call on the stack, then it could be dangerous to close
221 // via the MessageLoop since it may cause our destruction. 157 // now. Post a task that only gets invoked when there are no nested message
222 MessageLoop::current()->ReleaseSoon(FROM_HERE, this); 158 // loops.
159 MessageLoop::current()->PostNonNestableTask(FROM_HERE,
160 NewRunnableMethod(this, &RenderWidget::Close));
223 161
224 // If there is a Send call on the stack, then it could be dangerous to close 162 // Balances the AddRef taken when we called AddRoute.
225 // now. Instead, we wait until we get out of Send. 163 Release();
226 if (render_thread_->InSend()) {
227 DeferredCloses::Push(this);
228 } else {
229 Close();
230 }
231 } 164 }
232 165
233 void RenderWidget::OnResize(const gfx::Size& new_size, 166 void RenderWidget::OnResize(const gfx::Size& new_size,
234 const gfx::Rect& resizer_rect) { 167 const gfx::Rect& resizer_rect) {
235 // During shutdown we can just ignore this message. 168 // During shutdown we can just ignore this message.
236 if (!webwidget_) 169 if (!webwidget_)
237 return; 170 return;
238 171
239 // Remember the rect where the resize corner will be drawn. 172 // Remember the rect where the resize corner will be drawn.
240 resizer_rect_ = resizer_rect; 173 resizer_rect_ = resizer_rect;
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after
804 for (; i < plugin_window_moves_.size(); ++i) { 737 for (; i < plugin_window_moves_.size(); ++i) {
805 if (plugin_window_moves_[i].window == move.window) { 738 if (plugin_window_moves_[i].window == move.window) {
806 plugin_window_moves_[i] = move; 739 plugin_window_moves_[i] = move;
807 break; 740 break;
808 } 741 }
809 } 742 }
810 743
811 if (i == plugin_window_moves_.size()) 744 if (i == plugin_window_moves_.size())
812 plugin_window_moves_.push_back(move); 745 plugin_window_moves_.push_back(move);
813 } 746 }
OLDNEW
« chrome/common/child_process.cc ('K') | « chrome/renderer/render_widget.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698