Bug 27128 - Make Widget Ref-Counted.
Summary: Make Widget Ref-Counted.
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Plug-ins (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC OS X 10.5
: P2 Normal
Assignee: Nobody
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2009-07-09 13:36 PDT by Beth Dakin
Modified: 2009-07-10 12:27 PDT (History)
3 users (show)

See Also:


Attachments
Patch (49.95 KB, patch)
2009-07-09 13:37 PDT, Beth Dakin
hyatt: review-
Details | Formatted Diff | Diff
New Patch (53.09 KB, patch)
2009-07-09 14:51 PDT, Beth Dakin
hyatt: review+
Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Beth Dakin 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)
Comment 1 Beth Dakin 2009-07-09 13:37:30 PDT
Created attachment 32530 [details]
Patch
Comment 2 Dave Hyatt 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.
Comment 3 Oliver Hunt 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
Comment 4 Anders Carlsson 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();
Comment 5 Beth Dakin 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.
Comment 6 Dave Hyatt 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!
Comment 7 Dave Hyatt 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().
Comment 8 Beth Dakin 2009-07-09 15:28:15 PDT
Fixed with r45679.
Comment 9 Mark Rowe (bdash) 2009-07-09 22:32:59 PDT
Should this bug be closed then?
Comment 10 Beth Dakin 2009-07-10 12:27:24 PDT
Yes!