RESOLVED FIXED 27128
Make Widget Ref-Counted.
https://bugs.webkit.org/show_bug.cgi?id=27128
Summary Make Widget Ref-Counted.
Beth Dakin
Reported 2009-07-09 13:36:58 PDT
Here is a patch that makes Widget RefCounted. This fixes three crashes that we know about: <rdar://problem/7038831> REGRESSION (TOT): In Mail, a crash occurs at WebCore::Widget::afterMouseDown() after clicking To Do’s close box <rdar://problem/6978804> WER #16: Repro Access Violation in WebCore::PluginView::bindingInstance (1310178023) -and- <rdar://problem/6991251> WER #13: Crash in WebKit! WebCore::PluginView::performRequest+203 (1311461169)
Attachments
Patch (49.95 KB, patch)
2009-07-09 13:37 PDT, Beth Dakin
hyatt: review-
New Patch (53.09 KB, patch)
2009-07-09 14:51 PDT, Beth Dakin
hyatt: review+
Beth Dakin
Comment 1 2009-07-09 13:37:30 PDT
Dave Hyatt
Comment 2 2009-07-09 13:47:56 PDT
Comment on attachment 32530 [details] Patch > - const HashSet<Widget*>* viewChildren = children(); > - HashSet<Widget*>::const_iterator end = viewChildren->end(); > - for (HashSet<Widget*>::const_iterator current = viewChildren->begin(); current != end; ++current) > - if ((*current)->isFrameView()) > - static_cast<FrameView*>(*current)->layoutIfNeededRecursive(); > + const HashSet<RefPtr<Widget> >* viewChildren = children(); > + HashSet<RefPtr<Widget> >::const_iterator end = viewChildren->end(); > + for (HashSet<RefPtr<Widget> >::const_iterator current = viewChildren->begin(); current != end; ++current) { > + RefPtr<Widget> widget = (*current); > + if (widget->isFrameView()) > + static_cast<FrameView*>(widget.get())->layoutIfNeededRecursive(); > + } > I don't think the change to use a temporary variable here is helpful, since you've created refcounting churn. I think you should put it back the way it was and just use |current|. > Index: WebCore/rendering/RenderApplet.cpp > =================================================================== > --- WebCore/rendering/RenderApplet.cpp (revision 45662) > +++ WebCore/rendering/RenderApplet.cpp (working copy) > @@ -26,6 +26,7 @@ > #include "HTMLAppletElement.h" > #include "HTMLNames.h" > #include "HTMLParamElement.h" > +#include "Widget.h" > > namespace WebCore { > > @@ -71,7 +72,8 @@ void RenderApplet::createWidgetIfNecessa > > Frame* frame = document()->frame(); > ASSERT(frame); > - setWidget(frame->loader()->createJavaAppletWidget(IntSize(contentWidth, contentHeight), element, m_args)); > + RefPtr<Widget> widget = frame->loader()->createJavaAppletWidget(IntSize(contentWidth, contentHeight), element, m_args); > + setWidget(widget.get()); > } > I don't see any reason to use a temporary variable here? You're at the end of the function, so can't you just say: setWidget(frame->loader()->createJavaAppletWidget(...)); ? Other comments: Shouldn't setWidget take a PassRefPtr now, since RenderWidgets will be taking ownership of the widget? It seems like addChild should arguably take a PassRefPtr too, since the parent will also be taking ownership of the added child. I take back my objections to this patch. The fact that Scrollbars and FrameViews were already refcounted anyway makes this a really great cleanup. Let me see one more round. Thanks.
Oliver Hunt
Comment 3 2009-07-09 13:51:21 PDT
Comment on attachment 32530 [details] Patch Can you make the ScrollView constructor protected so that people can't accidentally go new ScrollView in future. The WebKit/win/ChangeLog entry appears to be duplicated
Anders Carlsson
Comment 4 2009-07-09 14:35:15 PDT
(In reply to comment #2) > (From update of attachment 32530 [details]) > > > - const HashSet<Widget*>* viewChildren = children(); > > - HashSet<Widget*>::const_iterator end = viewChildren->end(); > > - for (HashSet<Widget*>::const_iterator current = viewChildren->begin(); current != end; ++current) > > - if ((*current)->isFrameView()) > > - static_cast<FrameView*>(*current)->layoutIfNeededRecursive(); > > + const HashSet<RefPtr<Widget> >* viewChildren = children(); > > + HashSet<RefPtr<Widget> >::const_iterator end = viewChildren->end(); > > + for (HashSet<RefPtr<Widget> >::const_iterator current = viewChildren->begin(); current != end; ++current) { > > + RefPtr<Widget> widget = (*current); > > + if (widget->isFrameView()) > > + static_cast<FrameView*>(widget.get())->layoutIfNeededRecursive(); > > + } > > > > I don't think the change to use a temporary variable here is helpful, since > you've created refcounting churn. I think you should put it back the way it > was and just use |current|. > It could still be a temporary variable, just as long as you don't make it a RefPtr. Widget* widget = (*current).get();
Beth Dakin
Comment 5 2009-07-09 14:51:20 PDT
Created attachment 32533 [details] New Patch Here's a new patch that takes all of these comments into account.
Dave Hyatt
Comment 6 2009-07-09 14:59:39 PDT
Comment on attachment 32533 [details] New Patch Typo in ChangeLog: "setWidget() now takes a PassRefPtr. Also eemoved the manual ref of " "eemoved" should be "removed". ScrollView::platformAddChild never takes ownership of the Widget, so I don't think you needed to change any of those implementations. Those should just be platformAddChild(Widget*) still. You can undo that change and avoid having to touch a bunch of ScrollView port files. With those changes, r=me!
Dave Hyatt
Comment 7 2009-07-09 15:06:40 PDT
There is also some refcounting churn in addChild that you could avoid by using a raw local instead of a RefPtr local. Then use the PassRefPtr when passing in to m_children.add().
Beth Dakin
Comment 8 2009-07-09 15:28:15 PDT
Fixed with r45679.
Mark Rowe (bdash)
Comment 9 2009-07-09 22:32:59 PDT
Should this bug be closed then?
Beth Dakin
Comment 10 2009-07-10 12:27:24 PDT
Yes!
Note You need to log in before you can comment on or make changes to this bug.