[EFL] Remove redundant pipe write to prevent pipe buffer full.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 13 Dec 2012 11:00:12 +0000 (11:00 +0000)
committerByungwoo Lee <bw80.lee@samsung.com>
Wed, 27 Mar 2013 03:57:49 +0000 (12:57 +0900)
https://bugs.webkit.org/show_bug.cgi?id=101135

Patch by Byungwoo Lee <bw80.lee@samsung.com> on 2012-12-13
Reviewed by Gyuyoung Kim.

To prevent a source of a deadlock, remove the redundant pipe write
in wakeUp() function.

EFL uses ecore_pipe_write() to wake up main run loop, and the function
uses POSIX pipe write with O_NONBLOCK disabled.
With O_NONBLOCK disabled, when written data is more than PIPE_BUF,
pipe write will be blocked until it can be written.

Currently, every wakeUp() function calls ecore_pipe_write() to invoke
wakeUpEvent() callback. And this can make pipe buffer full status
which is the one reason of the lockup problem described in Bug 99494.

* platform/RunLoop.h:
(RunLoop):
* platform/efl/RunLoopEfl.cpp:
(WebCore::RunLoop::RunLoop):
(WebCore::RunLoop::wakeUpEvent):
(WebCore::RunLoop::wakeUp):

Change-Id: I0c46a64d885c929cb2ac265d4b0da020cd3db9a7
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@137580 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/RunLoop.h
Source/WebCore/platform/efl/RunLoopEfl.cpp

index c8e7ad5..1cc0e9a 100644 (file)
@@ -1,3 +1,29 @@
+2012-12-13  Byungwoo Lee  <bw80.lee@samsung.com>
+
+        [EFL] Remove redundant pipe write to prevent pipe buffer full.
+        https://bugs.webkit.org/show_bug.cgi?id=101135
+
+        Reviewed by Gyuyoung Kim.
+
+        To prevent a source of a deadlock, remove the redundant pipe write
+        in wakeUp() function.
+
+        EFL uses ecore_pipe_write() to wake up main run loop, and the function
+        uses POSIX pipe write with O_NONBLOCK disabled.
+        With O_NONBLOCK disabled, when written data is more than PIPE_BUF,
+        pipe write will be blocked until it can be written.
+
+        Currently, every wakeUp() function calls ecore_pipe_write() to invoke
+        wakeUpEvent() callback. And this can make pipe buffer full status
+        which is the one reason of the lockup problem described in Bug 99494.
+
+        * platform/RunLoop.h:
+        (RunLoop):
+        * platform/efl/RunLoopEfl.cpp:
+        (WebCore::RunLoop::RunLoop):
+        (WebCore::RunLoop::wakeUpEvent):
+        (WebCore::RunLoop::wakeUp):
+
 2012-12-11  Viatcheslav Ostapenko  <sl.ostapenko@samsung.com>
 
         Remove conversion to/from float and float division from ImageFrame::setRGBA
index fbfb837..57a87d7 100644 (file)
@@ -171,6 +171,9 @@ private:
     Mutex m_pipeLock;
     OwnPtr<Ecore_Pipe> m_pipe;
 
+    Mutex m_wakeUpEventRequestedLock;
+    bool m_wakeUpEventRequested;
+
     static void wakeUpEvent(void* data, void*, unsigned int);
 #endif
 };
index 8fd97dc..4406fdc 100644 (file)
@@ -43,6 +43,7 @@ namespace WebCore {
 
 RunLoop::RunLoop()
     : m_initEfl(false)
+    , m_wakeUpEventRequested(false)
 {
     if (!ecore_init()) {
         LOG_ERROR("could not init ecore.");
@@ -99,25 +100,41 @@ void RunLoop::stop()
 
 void RunLoop::wakeUpEvent(void* data, void*, unsigned int)
 {
-    static_cast<RunLoop*>(data)->performWork();
+    RunLoop* loop = static_cast<RunLoop*>(data);
+
+    {
+        MutexLocker locker(loop->m_wakeUpEventRequestedLock);
+        loop->m_wakeUpEventRequested = false;
+    }
+
+    loop->performWork();
 }
 
 void RunLoop::wakeUp()
 {
-    MutexLocker locker(m_pipeLock);
-#if ENABLE(TIZEN_RUNLOOP_WAKEUP_ERROR_WORKAROUND)
-    Eina_Bool result = false;
-    while(1) {
-        result = ecore_pipe_write(m_pipe.get(), wakupEcorePipeMessage, ecorePipeMessageSize);
-        if (result)
+    {
+        MutexLocker locker(m_wakeUpEventRequestedLock);
+        if (m_wakeUpEventRequested)
             return;
-
-        LOG_ERROR("Failed to write a wakupEcorePipeMessage\n");
-        m_pipe = adoptPtr(ecore_pipe_add(wakeUpEvent, this)); // due to OwnPtr, ecore_pipe_del is called automatically.
+        m_wakeUpEventRequested = true;
     }
+
+    {
+        MutexLocker locker(m_pipeLock);
+#if ENABLE(TIZEN_RUNLOOP_WAKEUP_ERROR_WORKAROUND)
+        Eina_Bool result = false;
+        while(1) {
+            result = ecore_pipe_write(m_pipe.get(), wakupEcorePipeMessage, ecorePipeMessageSize);
+            if (result)
+                return;
+
+            LOG_ERROR("Failed to write a wakupEcorePipeMessage\n");
+            m_pipe = adoptPtr(ecore_pipe_add(wakeUpEvent, this)); // due to OwnPtr, ecore_pipe_del is called automatically.
+        }
 #else
-    ecore_pipe_write(m_pipe.get(), wakupEcorePipeMessage, ecorePipeMessageSize);
+        ecore_pipe_write(m_pipe.get(), wakupEcorePipeMessage, ecorePipeMessageSize);
 #endif
+    }
 }
 
 RunLoop::TimerBase::TimerBase(RunLoop*)