Title: [110699] trunk/Source/WebCore
Revision
110699
Author
abe...@webkit.org
Date
2012-03-14 08:02:14 -0700 (Wed, 14 Mar 2012)

Log Message

[Qt] RunLoopQt is missing reentrancy guards
https://bugs.webkit.org/show_bug.cgi?id=80982

Patch by Simon Hausmann <simon.hausm...@nokia.com> on 2012-03-14
Reviewed by Tor Arne Vestbø.

Avoid recursive calls to RunLoop::performWork() with a simple
counting mechanism, to avoid out-of-order message dispatching.

* platform/qt/RunLoopQt.cpp:
(WebCore::RunLoop::TimerObject::TimerObject):
(WebCore::RunLoop::TimerObject::performWork):
(RunLoop::TimerObject):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (110698 => 110699)


--- trunk/Source/WebCore/ChangeLog	2012-03-14 14:41:26 UTC (rev 110698)
+++ trunk/Source/WebCore/ChangeLog	2012-03-14 15:02:14 UTC (rev 110699)
@@ -1,3 +1,18 @@
+2012-03-14  Simon Hausmann  <simon.hausm...@nokia.com>
+
+        [Qt] RunLoopQt is missing reentrancy guards
+        https://bugs.webkit.org/show_bug.cgi?id=80982
+
+        Reviewed by Tor Arne Vestbø.
+
+        Avoid recursive calls to RunLoop::performWork() with a simple
+        counting mechanism, to avoid out-of-order message dispatching.
+
+        * platform/qt/RunLoopQt.cpp:
+        (WebCore::RunLoop::TimerObject::TimerObject):
+        (WebCore::RunLoop::TimerObject::performWork):
+        (RunLoop::TimerObject):
+
 2012-03-14  Ilya Tikhonovsky  <loi...@chromium.org>
 
         Web Inspector: small improvement for HeapSnapshot performance ~12%.

Modified: trunk/Source/WebCore/platform/qt/RunLoopQt.cpp (110698 => 110699)


--- trunk/Source/WebCore/platform/qt/RunLoopQt.cpp	2012-03-14 14:41:26 UTC (rev 110698)
+++ trunk/Source/WebCore/platform/qt/RunLoopQt.cpp	2012-03-14 15:02:14 UTC (rev 110699)
@@ -39,13 +39,30 @@
 class RunLoop::TimerObject : public QObject {
     Q_OBJECT
 public:
-    TimerObject(RunLoop* runLoop) : m_runLoop(runLoop)
+    TimerObject(RunLoop* runLoop)
+        : m_runLoop(runLoop)
+        , m_pendingPerformWorkInvocations(0)
     {
         int methodIndex = metaObject()->indexOfMethod("performWork()");
         m_method = metaObject()->method(methodIndex);
     }
 
-    Q_SLOT void performWork() { m_runLoop->performWork(); }
+    Q_SLOT void performWork() {
+        // It may happen that a secondary thread adds more method invocations via
+        // RunLoop::dispatch(), which will schedule a call to this function. If during
+        // performWork() event loop messages get processed, it may happen that this
+        // function is called again. In this case we should protected ourselves against
+        // recursive - and thus out-of-order - message dispatching and instead perform
+        // the work serially.
+        m_pendingPerformWorkInvocations++;
+        if (m_pendingPerformWorkInvocations > 1)
+            return;
+
+        while (m_pendingPerformWorkInvocations) {
+            m_runLoop->performWork();
+            m_pendingPerformWorkInvocations--;
+        }
+    }
     inline void wakeUp() { m_method.invoke(this, Qt::QueuedConnection); }
 
 protected:
@@ -57,6 +74,7 @@
 private:
     RunLoop* m_runLoop;
     QMetaMethod m_method;
+    int m_pendingPerformWorkInvocations;
 };
 
 static QEventLoop* currentEventLoop;
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to