Commit 39b2c3ff authored by mitz@apple.com's avatar mitz@apple.com

Reviewed by Darin Adler and John Sullivan.

        - fix <rdar://problem/5914146> Crash at -[NSScrollView scrollWheel:]

        -[NSScrollView scrollWheel:] runs a nested event-tracking run loop
        in a mode that allows WebCore timers to fire and NSURLConnection
        callbacks to be dispatched, which can release the NSScrollView and
        cause it to be deallocated (one example is a DOM timer callback that
        removes a subframe from the document). This leads to a crash in
        -scrollView:.

        The fix is to replace the implementation of -[NSScrollView scrollWheel:]
        with one that optionally retains the receiver for the duration of the
        call.

        * page/mac/EventHandlerMac.mm:
        (WebCore::nsScrollViewScrollWheelShouldRetainSelf): Added.
        (WebCore::setNSScrollViewScrollWheelShouldRetainSelf): Added. Replaces
        the implementation of -[NSScrollView scrollWheel:] with the
        self-retaining one, and sets a static boolean that tells it whether to
        retain the receiver around the call to the original implementation.
        (WebCore::selfRetainingNSScrollViewScrollWheel): Added. If
        setNSScrollViewScrollWheelShouldRetainSelf(true) was called and this
        function is executing on the main thread, it retains the NSScrollView,
        invokes the original -[NSScrollView scrollWheel:], then releases the
        view. Otherwise it just calls through to the original implementation.
        (WebCore::EventHandler::passWheelEventToWidget): Added calls to
        setNSScrollViewScrollWheelShouldRetainSelf() around the call to
        -scrollWheel:.



git-svn-id: svn://svn.chromium.org/blink/trunk@42707 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 7ecd70eb
2009-04-20 Geoffrey Garen <ggaren@apple.com>
2009-04-21 Geoffrey Garen <ggaren@apple.com>
Reviewed by Mark Rowe.
2009-04-20 Geoffrey Garen <ggaren@apple.com>
2009-04-21 Geoffrey Garen <ggaren@apple.com>
Reviewed by Mark Rowe.
......
2009-04-20 Geoffrey Garen <ggaren@apple.com>
2009-04-21 Dan Bernstein <mitz@apple.com>
Reviewed by Darin Adler and John Sullivan.
- fix <rdar://problem/5914146> Crash at -[NSScrollView scrollWheel:]
-[NSScrollView scrollWheel:] runs a nested event-tracking run loop
in a mode that allows WebCore timers to fire and NSURLConnection
callbacks to be dispatched, which can release the NSScrollView and
cause it to be deallocated (one example is a DOM timer callback that
removes a subframe from the document). This leads to a crash in
-scrollView:.
The fix is to replace the implementation of -[NSScrollView scrollWheel:]
with one that optionally retains the receiver for the duration of the
call.
* page/mac/EventHandlerMac.mm:
(WebCore::nsScrollViewScrollWheelShouldRetainSelf): Added.
(WebCore::setNSScrollViewScrollWheelShouldRetainSelf): Added. Replaces
the implementation of -[NSScrollView scrollWheel:] with the
self-retaining one, and sets a static boolean that tells it whether to
retain the receiver around the call to the original implementation.
(WebCore::selfRetainingNSScrollViewScrollWheel): Added. If
setNSScrollViewScrollWheelShouldRetainSelf(true) was called and this
function is executing on the main thread, it retains the NSScrollView,
invokes the original -[NSScrollView scrollWheel:], then releases the
view. Otherwise it just calls through to the original implementation.
(WebCore::EventHandler::passWheelEventToWidget): Added calls to
setNSScrollViewScrollWheelShouldRetainSelf() around the call to
-scrollWheel:.
2009-04-21 Geoffrey Garen <ggaren@apple.com>
Reviewed by Mark Rowe.
......@@ -43,6 +43,7 @@
#include "RenderWidget.h"
#include "Scrollbar.h"
#include "Settings.h"
#include <objc/objc-runtime.h>
#include <wtf/StdLibExtras.h>
namespace WebCore {
......@@ -443,6 +444,40 @@ bool EventHandler::passSubframeEventToSubframe(MouseEventWithHitTestResults& eve
return false;
}
static IMP originalNSScrollViewScrollWheel;
static bool _nsScrollViewScrollWheelShouldRetainSelf;
static void selfRetainingNSScrollViewScrollWheel(NSScrollView *, SEL, NSEvent *);
static bool nsScrollViewScrollWheelShouldRetainSelf()
{
ASSERT(isMainThread());
return _nsScrollViewScrollWheelShouldRetainSelf;
}
static void setNSScrollViewScrollWheelShouldRetainSelf(bool shouldRetain)
{
ASSERT(isMainThread());
if (!originalNSScrollViewScrollWheel) {
Method method = class_getInstanceMethod(objc_getRequiredClass("NSScrollView"), @selector(scrollWheel:));
originalNSScrollViewScrollWheel = method_setImplementation(method, reinterpret_cast<IMP>(selfRetainingNSScrollViewScrollWheel));
}
_nsScrollViewScrollWheelShouldRetainSelf = shouldRetain;
}
static void selfRetainingNSScrollViewScrollWheel(NSScrollView *self, SEL selector, NSEvent *event)
{
bool shouldRetainSelf = isMainThread() && nsScrollViewScrollWheelShouldRetainSelf();
if (shouldRetainSelf)
[self retain];
originalNSScrollViewScrollWheel(self, selector, event);
if (shouldRetainSelf)
[self release];
}
bool EventHandler::passWheelEventToWidget(PlatformWheelEvent&, Widget* widget)
{
BEGIN_BLOCK_OBJC_EXCEPTIONS;
......@@ -459,7 +494,12 @@ bool EventHandler::passWheelEventToWidget(PlatformWheelEvent&, Widget* widget)
return false;
m_sendingEventToSubview = true;
// Work around <rdar://problem/6806810> which can cause -[NSScrollView scrollWheel:] to
// crash if the NSScrollView is released during timer or network callback dispatch
// in the nested tracking runloop that -[NSScrollView scrollWheel:] runs.
setNSScrollViewScrollWheelShouldRetainSelf(true);
[view scrollWheel:currentEvent().get()];
setNSScrollViewScrollWheelShouldRetainSelf(false);
m_sendingEventToSubview = false;
return true;
......
2009-04-20 Geoffrey Garen <ggaren@apple.com>
2009-04-21 Geoffrey Garen <ggaren@apple.com>
Reviewed by Mark Rowe.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment