Title: [94940] trunk/Source/WebKit2
Revision
94940
Author
[email protected]
Date
2011-09-11 20:34:20 -0700 (Sun, 11 Sep 2011)

Log Message

<rdar://problem/9878268> Pressing caps lock after closing a showModalDialog window results in WebProcess exiting

It's incorrect to try and use -[NSApplication run] to run nested runloops as it is not possible to
interrupt a nested invocation of -run without also causing outer invocations to exit after processing
their next event. We can avoid this issue by using -[NSApplication run] for the outermost invocation
of the main runloop, while using CFRunLoopRun for any nested invocations.

Reviewed by Anders Carlsson.

* Platform/RunLoop.h:
* Platform/mac/RunLoopMac.mm:
(RunLoop::RunLoop): Initialize the nesting level to 0.
(RunLoop::run): Bump the nesting level, and only use -[NSApplication run] for the outermost invocation of the
runloop. We also switch from -[NSRunloop run] to CFRunLoopRun as the former will only exit when it has no sources
left to process, while CFRunLoopRun will return immediately after CFRunLoopStop is called on it.
(RunLoop::stop): Only go down the NSApp path for the outermost invocation of the runloop.

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (94939 => 94940)


--- trunk/Source/WebKit2/ChangeLog	2011-09-12 03:31:18 UTC (rev 94939)
+++ trunk/Source/WebKit2/ChangeLog	2011-09-12 03:34:20 UTC (rev 94940)
@@ -1,3 +1,22 @@
+2011-09-11  Mark Rowe  <[email protected]>
+
+        <rdar://problem/9878268> Pressing caps lock after closing a showModalDialog window results in WebProcess exiting
+
+        It's incorrect to try and use -[NSApplication run] to run nested runloops as it is not possible to
+        interrupt a nested invocation of -run without also causing outer invocations to exit after processing
+        their next event. We can avoid this issue by using -[NSApplication run] for the outermost invocation
+        of the main runloop, while using CFRunLoopRun for any nested invocations.
+
+        Reviewed by Anders Carlsson.
+
+        * Platform/RunLoop.h:
+        * Platform/mac/RunLoopMac.mm:
+        (RunLoop::RunLoop): Initialize the nesting level to 0.
+        (RunLoop::run): Bump the nesting level, and only use -[NSApplication run] for the outermost invocation of the
+        runloop. We also switch from -[NSRunloop run] to CFRunLoopRun as the former will only exit when it has no sources
+        left to process, while CFRunLoopRun will return immediately after CFRunLoopStop is called on it.
+        (RunLoop::stop): Only go down the NSApp path for the outermost invocation of the runloop.
+
 2011-09-11  Balazs Kelemen  <[email protected]>
 
         [Qt][WK2] Qt layer should be hardened against C API versioning in the sense of build failures

Modified: trunk/Source/WebKit2/Platform/RunLoop.h (94939 => 94940)


--- trunk/Source/WebKit2/Platform/RunLoop.h	2011-09-12 03:31:18 UTC (rev 94939)
+++ trunk/Source/WebKit2/Platform/RunLoop.h	2011-09-12 03:34:20 UTC (rev 94940)
@@ -154,6 +154,7 @@
     static void performWork(void*);
     CFRunLoopRef m_runLoop;
     CFRunLoopSourceRef m_runLoopSource;
+    int m_nestingLevel;
 #elif PLATFORM(QT)
     typedef HashMap<int, TimerBase*> TimerMap;
     TimerMap m_activeTimers;

Modified: trunk/Source/WebKit2/Platform/mac/RunLoopMac.mm (94939 => 94940)


--- trunk/Source/WebKit2/Platform/mac/RunLoopMac.mm	2011-09-12 03:31:18 UTC (rev 94939)
+++ trunk/Source/WebKit2/Platform/mac/RunLoopMac.mm	2011-09-12 03:34:20 UTC (rev 94940)
@@ -41,9 +41,9 @@
 }
 
 RunLoop::RunLoop()
+    : m_runLoop(CFRunLoopGetCurrent())
+    , m_nestingLevel(0)
 {
-    m_runLoop = CFRunLoopGetCurrent();
-
     CFRunLoopSourceContext context = { 0, this, 0, 0, 0, 0, 0, 0, 0, performWork };
     m_runLoopSource = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
     CFRunLoopAddSource(m_runLoop, m_runLoopSource, kCFRunLoopCommonModes);
@@ -58,13 +58,16 @@
 
 void RunLoop::run()
 {
-    if (current() == main()) {
+    current()->m_nestingLevel++;
+    if (current() == main() && current()->m_nestingLevel == 1) {
         // Use -[NSApplication run] for the main run loop.
         [NSApp run];
     } else {
-        // Otherwise, use NSRunLoop. We do this because it sets up an autorelease pool for us.
-        [[NSRunLoop currentRunLoop] run];
-    }        
+        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+        CFRunLoopRun();
+        [pool drain];
+    }
+    current()->m_nestingLevel--;
 }
 
 void RunLoop::runForDuration(double duration)
@@ -76,7 +79,7 @@
 {
     ASSERT(m_runLoop == CFRunLoopGetCurrent());
     
-    if (m_runLoop == main()->m_runLoop) {
+    if (m_runLoop == main()->m_runLoop && m_nestingLevel == 1) {
         [NSApp stop:nil];
         NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined
                                             location:NSMakePoint(0, 0)
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to