WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
RESOLVED FIXED
Bug 53202
Async event handlers should not fire within a modal dialog
https://bugs.webkit.org/show_bug.cgi?id=53202
Summary
Async event handlers should not fire within a modal dialog
Mihai Parparita
Reported
2011-01-26 16:39:41 PST
Scroll event callbacks should not fire within a modal dialog
Attachments
Patch
(3.76 KB, patch)
2011-01-26 16:43 PST
,
Mihai Parparita
no flags
Details
Formatted Diff
Diff
Patch for landing
(3.88 KB, patch)
2011-01-27 22:40 PST
,
Mihai Parparita
no flags
Details
Formatted Diff
Diff
Patch
(5.16 KB, patch)
2011-01-28 14:03 PST
,
Mihai Parparita
no flags
Details
Formatted Diff
Diff
Patch
(8.03 KB, patch)
2011-01-28 15:13 PST
,
Mihai Parparita
no flags
Details
Formatted Diff
Diff
Patch for landing
(8.02 KB, patch)
2011-01-31 15:05 PST
,
Mihai Parparita
no flags
Details
Formatted Diff
Diff
Patch
(9.89 KB, patch)
2011-02-01 16:04 PST
,
Mihai Parparita
no flags
Details
Formatted Diff
Diff
Patch for landing
(10.14 KB, patch)
2011-02-01 16:13 PST
,
Mihai Parparita
no flags
Details
Formatted Diff
Diff
Show Obsolete
(6)
View All
Add attachment
proposed patch, testcase, etc.
Mihai Parparita
Comment 1
2011-01-26 16:43:38 PST
Created
attachment 80263
[details]
Patch
WebKit Commit Bot
Comment 2
2011-01-27 18:07:33 PST
Comment on
attachment 80263
[details]
Patch Rejecting
attachment 80263
[details]
from commit-queue. Failed to run "['./Tools/Scripts/webkit-patch', '--status-host=queues.webkit.org', '--bot-id=eseidel-cq-sf', 'bu..." exit_code: 2 Last 500 characters of output: ntation . fast/dom/Range .............................. fast/dom/Selection .. fast/dom/SelectorAPI ................. fast/dom/StyleSheet ................ fast/dom/Text . fast/dom/TreeWalker ........ fast/dom/Window .................................... fast/dom/Window/timer-resume-on-navigation-back.html -> failed Exiting early after 1 failures. 7521 tests run. 194.73s total testing time 7520 test cases (99%) succeeded 1 test case (<1%) had incorrect layout 4 test cases (<1%) had stderr output Full output:
http://queues.webkit.org/results/7574361
Mihai Parparita
Comment 3
2011-01-27 19:32:05 PST
It looks like this is preventing the document from going into the page cache because the default implementation of canSuspend returns false, and logCanCacheFrameDecision in PageCache.cpp checks for that. James, you may want to watch out for that in the patch on
bug 53188
. +Jeremy, since he expressed interest in using EventQueue. Jeremy, this patch makes the EventQueue constructor take a Document. Should it take a ScriptExecutionContext instead, if you want to use it in a worker?
Jeremy Orlow
Comment 4
2011-01-27 19:53:21 PST
+ ap because this is touching activeDOMObject (In reply to
comment #3
)
> It looks like this is preventing the document from going into the page cache because the default implementation of canSuspend returns false, and logCanCacheFrameDecision in PageCache.cpp checks for that. > > James, you may want to watch out for that in the patch on
bug 53188
. > > +Jeremy, since he expressed interest in using EventQueue. Jeremy, this patch makes the EventQueue constructor take a Document. Should it take a ScriptExecutionContext instead, if you want to use it in a worker?
I don't need it in a worker yet, so it's probably fine to leave it as is for now. (I'm just asserting isDocument and then casting for now.) Mihai, do you want it to cause things not to suspend? If not, you should just override the canSuspend function.
Mihai Parparita
Comment 5
2011-01-27 20:43:29 PST
(In reply to
comment #4
)
> Mihai, do you want it to cause things not to suspend? If not, you should just override the canSuspend function.
Yeah, I'm just going to override canSuspend.
Mihai Parparita
Comment 6
2011-01-27 22:40:48 PST
Created
attachment 80420
[details]
Patch for landing
Alexey Proskuryakov
Comment 7
2011-01-27 23:15:58 PST
Comment on
attachment 80420
[details]
Patch for landing Wait, how can EventQueue be an ActiveDOMObject when it's not a DOM object, and doesn't have a JS wrapper?
Jeremy Orlow
Comment 8
2011-01-28 00:13:29 PST
(In reply to
comment #7
)
> (From update of
attachment 80420
[details]
) > Wait, how can EventQueue be an ActiveDOMObject when it's not a DOM object, and doesn't have a JS wrapper?
I think we need to pull the notification aspect of ActiveDOMObject out from it. It seems like this is a pretty common need, even though these things aren't technically "ActiveDOMObjects". (Which is why IndexedDB and VoidCallback use it.) Thoughts?
Alexey Proskuryakov
Comment 9
2011-01-28 00:35:59 PST
The notification aspect of ActiveDOMObject is poorly thought through. Stop/canSuspend/suspend don't really reflect what we need - "suspending" for debugger, for page cache and for modal dialogs are all different. Different kinds of modal dialogs (alert() vs. showModalDialog() vs. print()) aren't necessarily all the same either. See e.g.
bug 45306 comment 9
.
Mihai Parparita
Comment 10
2011-01-28 08:06:36 PST
(In reply to
comment #9
)
> The notification aspect of ActiveDOMObject is poorly thought through. Stop/canSuspend/suspend don't really reflect what we need - "suspending" for debugger, for page cache and for modal dialogs are all different. Different kinds of modal dialogs (alert() vs. showModalDialog() vs. print()) aren't necessarily all the same either. > > See e.g.
bug 45306 comment 9
.
That was followed up by
http://trac.webkit.org/changeset/67432
, which added the ReasonForSuspension enum to ActiveDOMObject::suspend. Do you have in mind any further refactorings that would make this cleaner?
Alexey Proskuryakov
Comment 11
2011-01-28 08:39:18 PST
No, I don't have anything specific to suggest. If I were doing this, I'd have started with making a list of objects that need such notification, and their behaviors. We have a lot of objects that are notified in a custom way - see e.g.
bug 24030
or
bug 34679
. There is one good thing about custom code though - AsyncDOMObject is not particularly scalable, as we have to iterate a list that includes even objects that don't care about the current reason for suspension. An object that notifies objects it owns can be more discriminate. AsyncDOMObject even iterates objects that are not active right now!
James Robinson
Comment 12
2011-01-28 10:38:58 PST
(In reply to
comment #9
)
> The notification aspect of ActiveDOMObject is poorly thought through. Stop/canSuspend/suspend don't really reflect what we need - "suspending" for debugger, for page cache and for modal dialogs are all different. Different kinds of modal dialogs (alert() vs. showModalDialog() vs. print()) aren't necessarily all the same either. > > See e.g.
bug 45306 comment 9
.
In this case we do want to treat all of those (debugger, page cage, modal dialogs) in the same way, so I'm not sure I see the issue. EventQueues are 1:1 with Documents so efficiency is not a problem either. Do you have a specific issue with using ActiveDOMObject other than the name and the fact that it has been used for a different use case previously?
Mihai Parparita
Comment 13
2011-01-28 11:14:33 PST
How about this approach: 1. Create a Suspendable class, and move these methods from ActiveDOMObject into it: virtual bool canSuspend() const; virtual void suspend(ReasonForSuspension); virtual void resume(); virtual void stop(); 2. Make ActiveDOMObject inherit from Suspendable 3. Make the Suspendable constructor register instances with ScriptExecutionContext (which will put these in a separate list from m_activeDOMObjects) 4. Rename ScriptExecutionContext::suspend/resumeActiveDOMObjects to just ::suspend/resume, and have it loop over the list of Suspendables instead. 5. Make EventQueue (and RegisterAnimation) subclass Suspendable instead of ActiveDOMObject
Alexey Proskuryakov
Comment 14
2011-01-28 11:26:13 PST
Separating notification and GC protection responsibilities of ActiveDOMObjects is a reasonable step. I have some comments: - you probably don't want to have all suspendable objects in the list. E.g. if an animation isn't running, there is no reason to waste time on itin every suspend() call; - we do need to discuss specific needs of several interesting objects in detail to better assess the design - what exactly needs to be "suspended" in each case; - please don't make a special code path for EventQueue and RegisterAnimation only. Even if it's the best code path, it's not helpful if it adds to the mess of how objects are notified about document state changes.
> 4. Rename ScriptExecutionContext::suspend/resumeActiveDOMObjects to just ::suspend/resume, > and have it loop over the list of Suspendables instead.
This is not a great name - you won't suspend or resume ScriptExecutionContext itself in this method, all it does is notify some of the objects it tracks.
Mihai Parparita
Comment 15
2011-01-28 11:37:17 PST
(In reply to
comment #14
)
> Separating notification and GC protection responsibilities of ActiveDOMObjects is a reasonable step. I have some comments: > - you probably don't want to have all suspendable objects in the list. E.g. if an animation isn't running, there is no reason to waste time on it in every suspend() call;
I can't speak for other use-cases, but there is one EventQueue and one RequestAnimationFrameController per Document, so the overhead of calling suspend on them is not significant. I'd rather not make the design even more complicated (by allowing Suspendables to add/remove themselves from the list at will) unless there's a specific need for it.
> - we do need to discuss specific needs of several interesting objects in detail to better assess the design - what exactly needs to be "suspended" in each case;
Does this need to be done now? By making ActiveDOMObject inherit from Suspendable, existing ActiveDOMObject subclasses will not be affected. I agree it makes sense to investigate other ActiveDOMObject implementations to see if they could just use Suspendable instead, but I think that's beyond the scope of one patch.
> - please don't make a special code path for EventQueue and RegisterAnimation only. Even if it's the best code path, it's not helpful if it adds to the mess of how objects are notified about document state changes.
What specifically do you think is special for EventQueue and RegisterAnimation? I'm just proposing splitting ActiveDOMObject into two.
> This is not a great name - you won't suspend or resume ScriptExecutionContext itself in this method, all it does is notify some of the objects it tracks.
::suspendObjects perhaps? Any other suggestions?
Mihai Parparita
Comment 16
2011-01-28 12:22:40 PST
Actually, now that I look deeper, I see that we already have WebCore/page/SuspendableTimer. I can just make EventQueue use that instead of Timer directly. However, that doesn't help with RequestAnimationFrameController. Alexey, would SuspendableTimer be a good candidate for subclassing my proposed Suspendable class instead of ActiveDOMObject?
Mihai Parparita
Comment 17
2011-01-28 14:03:24 PST
Created
attachment 80494
[details]
Patch
Mihai Parparita
Comment 18
2011-01-28 14:04:59 PST
The new patch avoids using ActiveDOMObject directly by using SuspendableTimer, which seems tailor-made for this purpose (the fact that SuspendableTimer uses ActiveDOMObject itself is debatable, but that should hopefully not block this patch).
Jeremy Orlow
Comment 19
2011-01-28 14:12:24 PST
Comment on
attachment 80494
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=80494&action=review
> Source/WebCore/dom/Document.cpp:416 > + , m_eventQueue(adoptPtr(new EventQueue(this)))
EventQueue should have a ::create() which returns a PassOwnPtr. new should pretty much never be outside of a ::create
> Source/WebCore/dom/EventQueue.cpp:38 > +class EventQueueTimer : public SuspendableTimer {
Is all of this just to avoid including SuspendableTimer.h in EventQueue.h? If so, I'm not sure it's worth it.
> Source/WebCore/dom/EventQueue.cpp:41 > + explicit EventQueueTimer(EventQueue* eventQueue, ScriptExecutionContext* context)
no explicit
> Source/WebCore/dom/EventQueue.h:52 > + explicit EventQueue(ScriptExecutionContext*);
Make private and add a factory method
> Source/WebCore/dom/EventQueue.h:57 > +
remove tab
Dmitry Titov
Comment 20
2011-01-28 14:48:13 PST
Just a note: DRT now can test operations under modal dialogs using showModalDialog(). See
http://trac.webkit.org/changeset/61599
for more details.
Mihai Parparita
Comment 21
2011-01-28 15:13:24 PST
Created
attachment 80504
[details]
Patch
Mihai Parparita
Comment 22
2011-01-28 15:14:57 PST
(In reply to
comment #19
)
> EventQueue should have a ::create() which returns a PassOwnPtr. new should pretty much never be outside of a ::create
Changed.
> > Source/WebCore/dom/EventQueue.cpp:38 > > +class EventQueueTimer : public SuspendableTimer { > > Is all of this just to avoid including SuspendableTimer.h in EventQueue.h? If so, I'm not sure it's worth it.
No, it's because SuspendableTimer (unlike Timer) does not take the method that you want called as a constructor argument, instead you have to implement fired().
> > Source/WebCore/dom/EventQueue.cpp:41 > > + explicit EventQueueTimer(EventQueue* eventQueue, ScriptExecutionContext* context) > > no explicit
Oops, left over from when it only had one argument. Removed.
> > Source/WebCore/dom/EventQueue.h:52 > > + explicit EventQueue(ScriptExecutionContext*); > > Make private and add a factory method
Done.
> > Source/WebCore/dom/EventQueue.h:57 > > + > > remove tab
Done. (In reply to
comment #20
)
> Just a note: DRT now can test operations under modal dialogs using showModalDialog(). See
http://trac.webkit.org/changeset/61599
for more details.
Thanks for the pointer, added a layout test.
Jeremy Orlow
Comment 23
2011-01-28 15:27:04 PST
(In reply to
comment #22
)
> (In reply to
comment #19
) > > > Source/WebCore/dom/EventQueue.cpp:38 > > > +class EventQueueTimer : public SuspendableTimer { > > > > Is all of this just to avoid including SuspendableTimer.h in EventQueue.h? If so, I'm not sure it's worth it. > > No, it's because SuspendableTimer (unlike Timer) does not take the method that you want called as a constructor argument, instead you have to implement fired().
Sure, but why can't EventQueue implement fired rather than using its own method? I guess it's slightly less clear, but a comment would mostly fix that. I don't feel strongly though.
Mihai Parparita
Comment 24
2011-01-28 17:41:23 PST
(In reply to
comment #23
)
> Sure, but why can't EventQueue implement fired rather than using its own method? I guess it's slightly less clear, but a comment would mostly fix that. > > I don't feel strongly though.
You mean have EventQueue subclass SuspendableTimer? That doesn't seem right.
James Robinson
Comment 25
2011-01-30 18:56:36 PST
Comment on
attachment 80504
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=80504&action=review
Looks good to me. For posterity this behavior is specified by
http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-alert
(for alert(), confirm(), print()) and
http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-showmodaldialog
step 5 for showModalDialog().
> Source/WebCore/dom/EventQueue.h:59 > + virtual ~EventQueue();
why virtual? I can't find any subclasses of EventQueue in the codebase currently
Mihai Parparita
Comment 26
2011-01-31 15:05:17 PST
Created
attachment 80684
[details]
Patch for landing
Mihai Parparita
Comment 27
2011-01-31 15:05:50 PST
(In reply to
comment #25
)
> > Source/WebCore/dom/EventQueue.h:59 > > + virtual ~EventQueue(); > > why virtual? I can't find any subclasses of EventQueue in the codebase currently
No reason for it to be virtual, removed.
WebKit Commit Bot
Comment 28
2011-02-01 01:21:12 PST
Comment on
attachment 80684
[details]
Patch for landing Clearing flags on attachment: 80684 Committed
r77230
: <
http://trac.webkit.org/changeset/77230
>
WebKit Commit Bot
Comment 29
2011-02-01 01:21:19 PST
All reviewed patches have been landed. Closing bug.
Yury Semikhatsky
Comment 30
2011-02-01 04:19:16 PST
Reopening since the change was rolled out in
http://trac.webkit.org/changeset/77241
due to layout tests crashes on Chromium Debug bots:
http://build.chromium.org/p/chromium.webkit/builders/Webkit%20Linux%20(dbg)(1)/builds/787
Mihai Parparita
Comment 31
2011-02-01 16:04:21 PST
Created
attachment 80846
[details]
Patch
Mihai Parparita
Comment 32
2011-02-01 16:06:36 PST
Delta from previous patch is in SuspendableTimer, it was suspending the timer (and restarting it) even when it hadn't been started. I made SuspendableTimer keep track of whether or not the timer had been started via m_active.
James Robinson
Comment 33
2011-02-01 16:10:09 PST
Comment on
attachment 80846
[details]
Patch View in context:
https://bugs.webkit.org/attachment.cgi?id=80846&action=review
Looks good, although I wonder if we shouldn't assimilate the m_suspend timer instead. Also while you're in SuspendableTimer.h can you make the c'tor explicit?
> Source/WebCore/page/SuspendableTimer.h:50 > + bool m_active;
nit: this should be declared after the doubles so it packs better.
Mihai Parparita
Comment 34
2011-02-01 16:13:23 PST
Created
attachment 80848
[details]
Patch for landing
Mihai Parparita
Comment 35
2011-02-01 16:15:20 PST
(In reply to
comment #33
)
> Looks good, although I wonder if we shouldn't assimilate the m_suspend timer instead.
As discussed in person, m_suspended is about making sure that suspend()/resume() calls are balanced (and is thus relevant to this being an ActiveDOMObject subclass), while m_active is about the timer being started, so they don't really do the same thing.
> Also while you're in SuspendableTimer.h can you make the c'tor explicit?
Done.
> > Source/WebCore/page/SuspendableTimer.h:50 > > + bool m_active; > > nit: this should be declared after the doubles so it packs better.
Done.
WebKit Commit Bot
Comment 36
2011-02-01 18:39:43 PST
Comment on
attachment 80848
[details]
Patch for landing Clearing flags on attachment: 80848 Committed
r77355
: <
http://trac.webkit.org/changeset/77355
>
WebKit Commit Bot
Comment 37
2011-02-01 18:39:50 PST
All reviewed patches have been landed. Closing bug.
Eric Seidel (no email)
Comment 38
2011-02-02 14:21:04 PST
SUCCESS: Build 14507 (
r77358
) was the first to show failures: set([u'fast/events/pageshow-pagehide-on-back-cached.html', u'fast/history/timed-refresh-in-cached-frame.html'])
http://build.webkit.org/results/SnowLeopard%20Intel%20Leaks/r77400%20(14522)/results.html
I think this checkin is to blame.
Mihai Parparita
Comment 39
2011-02-02 17:05:37 PST
(In reply to
comment #38
)
> SUCCESS: Build 14507 (
r77358
) was the first to show failures: set([u'fast/events/pageshow-pagehide-on-back-cached.html', u'fast/history/timed-refresh-in-cached-frame.html']) > >
http://build.webkit.org/results/SnowLeopard%20Intel%20Leaks/r77400%20(14522)/results.html
> > I think this checkin is to blame.
Filed
bug 53648
about this.
Philippe Normand
Comment 40
2011-02-03 01:32:09 PST
This patch broke a test on GTK as well, see
bug 53667
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug