Title: [109161] trunk/Source/WebCore
Revision
109161
Author
[email protected]
Date
2012-02-28 15:44:56 -0800 (Tue, 28 Feb 2012)

Log Message

[GTK] Add support for nested event loops in RunLoop
https://bugs.webkit.org/show_bug.cgi?id=79499

Reviewed by Martin Robinson.

Run a new nested mainloop if the main event loop is already
running when calling to RunLoop::run(), and take care of stopping
the right main loop too when RunLoop::stop() is invoked.

* platform/RunLoop.h:
(RunLoop):
* platform/gtk/RunLoopGtk.cpp:
(WebCore::RunLoop::RunLoop):
(WebCore::RunLoop::~RunLoop):
(WebCore::RunLoop::run):
(WebCore::RunLoop::innermostLoop):
(WebCore::RunLoop::pushNestedMainLoop):
(WebCore::RunLoop::popNestedMainLoop):
(WebCore):
(WebCore::RunLoop::stop):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (109160 => 109161)


--- trunk/Source/WebCore/ChangeLog	2012-02-28 23:28:58 UTC (rev 109160)
+++ trunk/Source/WebCore/ChangeLog	2012-02-28 23:44:56 UTC (rev 109161)
@@ -1,3 +1,26 @@
+2012-02-29  Mario Sanchez Prada  <[email protected]>
+
+        [GTK] Add support for nested event loops in RunLoop
+        https://bugs.webkit.org/show_bug.cgi?id=79499
+
+        Reviewed by Martin Robinson.
+
+        Run a new nested mainloop if the main event loop is already
+        running when calling to RunLoop::run(), and take care of stopping
+        the right main loop too when RunLoop::stop() is invoked.
+
+        * platform/RunLoop.h:
+        (RunLoop):
+        * platform/gtk/RunLoopGtk.cpp:
+        (WebCore::RunLoop::RunLoop):
+        (WebCore::RunLoop::~RunLoop):
+        (WebCore::RunLoop::run):
+        (WebCore::RunLoop::innermostLoop):
+        (WebCore::RunLoop::pushNestedMainLoop):
+        (WebCore::RunLoop::popNestedMainLoop):
+        (WebCore):
+        (WebCore::RunLoop::stop):
+
 2012-02-28  Julien Chaffraix  <[email protected]>
 
         Move RenderLayer::size() calls to a common function

Modified: trunk/Source/WebCore/platform/RunLoop.h (109160 => 109161)


--- trunk/Source/WebCore/platform/RunLoop.h	2012-02-28 23:28:58 UTC (rev 109160)
+++ trunk/Source/WebCore/platform/RunLoop.h	2012-02-28 23:44:56 UTC (rev 109161)
@@ -151,10 +151,12 @@
 #elif PLATFORM(GTK)
 public:
     static gboolean queueWork(RunLoop*);
-    GMainLoop* mainLoop();
+    GMainLoop* innermostLoop();
+    void pushNestedMainLoop(GMainLoop*);
+    void popNestedMainLoop();
 private:
     GRefPtr<GMainContext> m_runLoopContext;
-    GRefPtr<GMainLoop> m_runLoopMain;
+    Vector<GRefPtr<GMainLoop> > m_runLoopMainLoops;
 #endif
 };
 

Modified: trunk/Source/WebCore/platform/gtk/RunLoopGtk.cpp (109160 => 109161)


--- trunk/Source/WebCore/platform/gtk/RunLoopGtk.cpp	2012-02-28 23:28:58 UTC (rev 109160)
+++ trunk/Source/WebCore/platform/gtk/RunLoopGtk.cpp	2012-02-28 23:44:56 UTC (rev 109161)
@@ -27,6 +27,7 @@
 #include "config.h"
 #include "RunLoop.h"
 
+#include <gdk/gdk.h>
 #include <glib.h>
 
 namespace WebCore {
@@ -36,29 +37,64 @@
     // g_main_context_default() doesn't add an extra reference.
     m_runLoopContext = g_main_context_default();
     ASSERT(m_runLoopContext);
-    m_runLoopMain = adoptGRef(g_main_loop_new(m_runLoopContext.get(), FALSE));
-    ASSERT(m_runLoopMain);
+    GRefPtr<GMainLoop> innermostLoop = adoptGRef(g_main_loop_new(m_runLoopContext.get(), FALSE));
+    ASSERT(innermostLoop);
+    m_runLoopMainLoops.append(innermostLoop);
 }
 
 RunLoop::~RunLoop()
 {
-    if (m_runLoopMain && g_main_loop_is_running(m_runLoopMain.get()))
-        g_main_loop_quit(m_runLoopMain.get());
+    for (int i = m_runLoopMainLoops.size() - 1; i >= 0; --i) {
+        if (!g_main_loop_is_running(m_runLoopMainLoops[i].get()))
+            continue;
+        g_main_loop_quit(m_runLoopMainLoops[i].get());
+    }
 }
 
 void RunLoop::run()
 {
-    g_main_loop_run(RunLoop::main()->mainLoop());
+    RunLoop* mainRunLoop = RunLoop::main();
+    GMainLoop* innermostLoop = mainRunLoop->innermostLoop();
+    if (!g_main_loop_is_running(innermostLoop)) {
+        g_main_loop_run(innermostLoop);
+        return;
+    }
+
+    // Create and run a nested loop if the innermost one was already running.
+    GMainLoop* nestedMainLoop = g_main_loop_new(0, FALSE);
+    mainRunLoop->pushNestedMainLoop(nestedMainLoop);
+    g_main_loop_run(nestedMainLoop);
+    mainRunLoop->popNestedMainLoop();
 }
 
-GMainLoop* RunLoop::mainLoop()
+GMainLoop* RunLoop::innermostLoop()
 {
-    return m_runLoopMain.get();
+    // The innermost main loop should always be there.
+    ASSERT(!m_runLoopMainLoops.isEmpty());
+    return m_runLoopMainLoops[0].get();
 }
 
+void RunLoop::pushNestedMainLoop(GMainLoop* nestedLoop)
+{
+    // The innermost main loop should always be there.
+    ASSERT(!m_runLoopMainLoops.isEmpty());
+    m_runLoopMainLoops.append(adoptGRef(nestedLoop));
+}
+
+void RunLoop::popNestedMainLoop()
+{
+    // The innermost main loop should always be there.
+    ASSERT(!m_runLoopMainLoops.isEmpty());
+    m_runLoopMainLoops.removeLast();
+}
+
 void RunLoop::stop()
 {
-    g_main_loop_quit(m_runLoopMain.get());
+    // The innermost main loop should always be there.
+    ASSERT(!m_runLoopMainLoops.isEmpty());
+    GRefPtr<GMainLoop> lastMainLoop = m_runLoopMainLoops.last();
+    if (g_main_loop_is_running(lastMainLoop.get()))
+        g_main_loop_quit(lastMainLoop.get());
 }
 
 gboolean RunLoop::queueWork(RunLoop* runLoop)
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to