[EFL][WK2] Add RunLoopEfl and WorkQueueEfl
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 28 Mar 2012 02:02:18 +0000 (02:02 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 28 Mar 2012 02:02:18 +0000 (02:02 +0000)
https://bugs.webkit.org/show_bug.cgi?id=62777

Patch by YoungTaeck Song <youngtaeck.song@samsung.com> on 2012-03-27
Reviewed by Hajime Morita.

Source/WebCore:

Add initial version RunLoopEfl for WebKit2 Efl.

* platform/RunLoop.h:
(TimerBase):
(RunLoop):
* platform/efl/RunLoopEfl.cpp:
(WebCore::RunLoop::RunLoop):
(WebCore::RunLoop::~RunLoop):
(WebCore):
(WebCore::RunLoop::run):
(WebCore::RunLoop::stop):
(WebCore::RunLoop::wakeUpEvent):
(WebCore::RunLoop::wakeUp):
(WebCore::RunLoop::TimerBase::TimerBase):
(WebCore::RunLoop::TimerBase::~TimerBase):
(WebCore::RunLoop::TimerBase::timerFired):
(WebCore::RunLoop::TimerBase::start):
(WebCore::RunLoop::TimerBase::stop):
(WebCore::RunLoop::TimerBase::isActive):

Source/WebKit2:

Add initial version WorkQueueEfl for WebKit2 Efl.

* Platform/CoreIPC/Connection.h:
* Platform/CoreIPC/unix/ConnectionUnix.cpp:
(CoreIPC::Connection::platformInvalidate):
(CoreIPC::Connection::open):
* Platform/PlatformProcessIdentifier.h:
(WebKit):
* Platform/WorkQueue.h:
(WorkQueue):
* Platform/efl/WorkQueueEfl.cpp: Added.
(TimerWorkItem):
(TimerWorkItem::TimerWorkItem):
(TimerWorkItem::~TimerWorkItem):
(TimerWorkItem::function):
(TimerWorkItem::queue):
(TimerWorkItem::timerID):
(WorkQueue::platformInitialize):
(WorkQueue::platformInvalidate):
(WorkQueue::performWork):
(WorkQueue::performFdWork):
(WorkQueue::sendMessageToThread):
(WorkQueue::workQueueThread):
(WorkQueue::registerSocketEventHandler):
(WorkQueue::unregisterSocketEventHandler):
(WorkQueue::dispatch):
(WorkQueue::timerFired):
(WorkQueue::dispatchAfterDelay):
* PlatformEfl.cmake:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@112353 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/platform/RunLoop.h
Source/WebCore/platform/efl/RunLoopEfl.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/Platform/CoreIPC/Connection.h
Source/WebKit2/Platform/CoreIPC/unix/ConnectionUnix.cpp
Source/WebKit2/Platform/PlatformProcessIdentifier.h
Source/WebKit2/Platform/WorkQueue.h
Source/WebKit2/Platform/efl/WorkQueueEfl.cpp [new file with mode: 0644]
Source/WebKit2/PlatformEfl.cmake

index 59f709a..e090791 100644 (file)
@@ -1,3 +1,30 @@
+2012-03-27  YoungTaeck Song  <youngtaeck.song@samsung.com>
+
+        [EFL][WK2] Add RunLoopEfl and WorkQueueEfl
+        https://bugs.webkit.org/show_bug.cgi?id=62777
+
+        Reviewed by Hajime Morita.
+
+        Add initial version RunLoopEfl for WebKit2 Efl.
+
+        * platform/RunLoop.h:
+        (TimerBase):
+        (RunLoop):
+        * platform/efl/RunLoopEfl.cpp:
+        (WebCore::RunLoop::RunLoop):
+        (WebCore::RunLoop::~RunLoop):
+        (WebCore):
+        (WebCore::RunLoop::run):
+        (WebCore::RunLoop::stop):
+        (WebCore::RunLoop::wakeUpEvent):
+        (WebCore::RunLoop::wakeUp):
+        (WebCore::RunLoop::TimerBase::TimerBase):
+        (WebCore::RunLoop::TimerBase::~TimerBase):
+        (WebCore::RunLoop::TimerBase::timerFired):
+        (WebCore::RunLoop::TimerBase::start):
+        (WebCore::RunLoop::TimerBase::stop):
+        (WebCore::RunLoop::TimerBase::isActive):
+
 2012-03-27  Benjamin Poulain  <bpoulain@apple.com>
 
         Reinforce Geolocation to prevent accidental leak of the user position
index f08a042..40b4194 100644 (file)
 #include <wtf/gobject/GRefPtr.h>
 #endif
 
+#if PLATFORM(EFL)
+#include <Ecore.h>
+#endif
+
 namespace WebCore {
 
 class RunLoop {
@@ -95,6 +99,10 @@ public:
         void clearTimerSource();
         GRefPtr<GSource> m_timerSource;
         gboolean m_isRepeating;
+#elif PLATFORM(EFL)
+        static bool timerFired(void* data);
+        OwnPtr<Ecore_Timer> m_timer;
+        bool m_isRepeating;
 #endif
     };
 
@@ -157,6 +165,10 @@ public:
 private:
     GRefPtr<GMainContext> m_runLoopContext;
     Vector<GRefPtr<GMainLoop> > m_runLoopMainLoops;
+#elif PLATFORM(EFL)
+    bool m_initEfl;
+    OwnPtr<Ecore_Pipe> m_pipe;
+    static void wakeUpEvent(void* data, void*, unsigned int);
 #endif
 };
 
index e820788..f299d8e 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2012 ProFUSION embedded systems. All rights reserved.
+ * Copyright (C) 2012 Samsung Electronics
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #include "config.h"
 #include "RunLoop.h"
 
-#include "NotImplemented.h"
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+#include <Ecore_File.h>
+#include <Edje.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
+
+static const int ecorePipeMessageSize = 1;
+static const char wakupEcorePipeMessage[] = "W";
 
 namespace WebCore {
 
 RunLoop::RunLoop()
+    : m_initEfl(false)
 {
-    notImplemented();
+    if (!ecore_init()) {
+        LOG_ERROR("could not init ecore.");
+        return;
+    }
+
+    if (!ecore_evas_init()) {
+        LOG_ERROR("could not init ecore_evas.");
+        goto errorEcoreEvas;
+    }
+
+    if (!ecore_file_init()) {
+        LOG_ERROR("could not init ecore_file.");
+        goto errorEcoreFile;
+    }
+
+    if (!edje_init()) {
+        LOG_ERROR("could not init edje.");
+        goto errorEdje;
+    }
+
+    m_pipe = adoptPtr(ecore_pipe_add(wakeUpEvent, this));
+    m_initEfl = true;
+
+    return;
+
+errorEdje:
+    ecore_file_shutdown();
+errorEcoreFile:
+    ecore_evas_shutdown();
+errorEcoreEvas:
+    ecore_shutdown();
 }
 
 RunLoop::~RunLoop()
 {
-    notImplemented();
+    if (m_initEfl) {
+        edje_shutdown();
+        ecore_file_shutdown();
+        ecore_evas_shutdown();
+        ecore_shutdown();
+    }
+}
+
+void RunLoop::run()
+{
+    ecore_main_loop_begin();
+}
+
+void RunLoop::stop()
+{
+    ecore_main_loop_quit();
+}
+
+void RunLoop::wakeUpEvent(void* data, void*, unsigned int)
+{
+    static_cast<RunLoop*>(data)->performWork();
 }
 
 void RunLoop::wakeUp()
 {
-    notImplemented();
+    ecore_pipe_write(m_pipe.get(), wakupEcorePipeMessage, ecorePipeMessageSize);
+}
+
+RunLoop::TimerBase::TimerBase(RunLoop*)
+    : m_isRepeating(false)
+{
+}
+
+RunLoop::TimerBase::~TimerBase()
+{
+    stop();
+}
+
+bool RunLoop::TimerBase::timerFired(void* data)
+{
+    RunLoop::TimerBase* timer = static_cast<RunLoop::TimerBase*>(data);
+
+    timer->fired();
+
+    if (!timer->m_isRepeating) {
+        timer->m_timer = nullptr;
+        return ECORE_CALLBACK_CANCEL;
+    }
+
+    return ECORE_CALLBACK_RENEW;
+}
+
+void RunLoop::TimerBase::start(double nextFireInterval, bool repeat)
+{
+    m_isRepeating = repeat;
+    m_timer = adoptPtr(ecore_timer_add(nextFireInterval, reinterpret_cast<Ecore_Task_Cb>(timerFired), this));
+}
+
+void RunLoop::TimerBase::stop()
+{
+    m_timer = nullptr;
+}
+
+bool RunLoop::TimerBase::isActive() const
+{
+    return (m_timer) ? true : false;
 }
 
 } // namespace WebCore
index 41094dd..e3ff7e4 100644 (file)
@@ -1,3 +1,40 @@
+2012-03-27  YoungTaeck Song  <youngtaeck.song@samsung.com>
+
+        [EFL][WK2] Add RunLoopEfl and WorkQueueEfl
+        https://bugs.webkit.org/show_bug.cgi?id=62777
+
+        Reviewed by Hajime Morita.
+
+        Add initial version WorkQueueEfl for WebKit2 Efl.
+
+        * Platform/CoreIPC/Connection.h:
+        * Platform/CoreIPC/unix/ConnectionUnix.cpp:
+        (CoreIPC::Connection::platformInvalidate):
+        (CoreIPC::Connection::open):
+        * Platform/PlatformProcessIdentifier.h:
+        (WebKit):
+        * Platform/WorkQueue.h:
+        (WorkQueue):
+        * Platform/efl/WorkQueueEfl.cpp: Added.
+        (TimerWorkItem):
+        (TimerWorkItem::TimerWorkItem):
+        (TimerWorkItem::~TimerWorkItem):
+        (TimerWorkItem::function):
+        (TimerWorkItem::queue):
+        (TimerWorkItem::timerID):
+        (WorkQueue::platformInitialize):
+        (WorkQueue::platformInvalidate):
+        (WorkQueue::performWork):
+        (WorkQueue::performFdWork):
+        (WorkQueue::sendMessageToThread):
+        (WorkQueue::workQueueThread):
+        (WorkQueue::registerSocketEventHandler):
+        (WorkQueue::unregisterSocketEventHandler):
+        (WorkQueue::dispatch):
+        (WorkQueue::timerFired):
+        (WorkQueue::dispatchAfterDelay):
+        * PlatformEfl.cmake:
+
 2012-03-27  Anders Carlsson  <andersca@apple.com>
 
         Plug-ins using the Core Animation drawing model should work when hosting the layer tree in the window server
index 81553ae..c2ff7f1 100644 (file)
@@ -46,7 +46,7 @@
 class QSocketNotifier;
 #endif
 
-#if PLATFORM(QT) || PLATFORM(GTK)
+#if PLATFORM(QT) || PLATFORM(GTK) || PLATFORM(EFL)
 #include "PlatformProcessIdentifier.h"
 #endif
 
index d54aff8..7cb1f32 100644 (file)
@@ -153,6 +153,10 @@ void Connection::platformInvalidate()
     m_socketNotifier = 0;
 #endif
 
+#if PLATFORM(EFL)
+    m_connectionQueue.unregisterSocketEventHandler(m_socketDescriptor);
+#endif
+
     m_socketDescriptor = -1;
     m_isConnected = false;
 }
@@ -423,6 +427,8 @@ bool Connection::open()
 #elif PLATFORM(GTK)
     m_connectionQueue.registerEventSourceHandler(m_socketDescriptor, (G_IO_HUP | G_IO_ERR), bind(&Connection::connectionDidClose, this));
     m_connectionQueue.registerEventSourceHandler(m_socketDescriptor, G_IO_IN, bind(&Connection::readyReadHandler, this));
+#elif PLATFORM(EFL)
+    m_connectionQueue.registerSocketEventHandler(m_socketDescriptor, bind(&Connection::readyReadHandler, this));
 #endif
 
     // Schedule a call to readyReadHandler. Data may have arrived before installation of the signal
index 5022da7..9cafd32 100644 (file)
@@ -46,6 +46,8 @@ typedef void* GPid;
 typedef int GPid;
 #endif
 typedef GPid PlatformProcessIdentifier;
+#elif PLATFORM(EFL)
+typedef pid_t PlatformProcessIdentifier;
 #endif
 
 } // namespace WebKit 
index ed894cb..d630dc0 100644 (file)
 #include <wtf/Threading.h>
 #include <wtf/Vector.h>
 
+#if (PLATFORM(QT) && !OS(DARWIN)) || PLATFORM(GTK) || PLATFORM(EFL)
+#include "PlatformProcessIdentifier.h"
+#endif
+
 #if PLATFORM(QT) && !OS(DARWIN)
 #include <QSocketNotifier>
-#include "PlatformProcessIdentifier.h"
 class QObject;
 class QThread;
 #elif PLATFORM(GTK)
-#include "PlatformProcessIdentifier.h"
 #include <wtf/gobject/GRefPtr.h>
 typedef gboolean (*GSourceFunc) (gpointer data);
+#elif PLATFORM(EFL)
+#include <Ecore.h>
 #endif
 
 class WorkQueue {
@@ -90,6 +94,9 @@ public:
     void registerEventSourceHandler(int, int, const Function<void()>&);
     void unregisterEventSourceHandler(int);
     void dispatchOnTermination(WebKit::PlatformProcessIdentifier, const Function<void()>&);
+#elif PLATFORM(EFL)
+    void registerSocketEventHandler(int, const Function<void()>&);
+    void unregisterSocketEventHandler(int);
 #endif
 
 private:
@@ -177,6 +184,26 @@ private:
     class EventSource;
     HashMap<int, Vector<EventSource*> > m_eventSources;
     typedef HashMap<int, Vector<EventSource*> >::iterator EventSourceIterator; 
+#elif PLATFORM(EFL)
+    fd_set m_fileDescriptorSet;
+    int m_maxFileDescriptor;
+    int m_readFromPipeDescriptor;
+    int m_writeToPipeDescriptor;
+    bool m_threadLoop;
+
+    Vector<Function<void()> > m_workItemQueue;
+    Mutex m_workItemQueueLock;
+
+    int m_socketDescriptor;
+    Function<void()> m_socketEventHandler;
+
+    HashMap<int, OwnPtr<Ecore_Timer> > m_timers;
+
+    void sendMessageToThread(const char*);
+    static void* workQueueThread(WorkQueue*);
+    void performWork();
+    void performFileDescriptorWork();
+    static bool timerFired(void*);
 #endif
 };
 
diff --git a/Source/WebKit2/Platform/efl/WorkQueueEfl.cpp b/Source/WebKit2/Platform/efl/WorkQueueEfl.cpp
new file mode 100644 (file)
index 0000000..3a39ba9
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+    Copyright (C) 2012 Samsung Electronics
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public License
+    along with this library; see the file COPYING.LIB.  If not, write to
+    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+    Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "WorkQueue.h"
+
+#include <wtf/Assertions.h>
+
+class TimerWorkItem {
+public:
+    TimerWorkItem(int timerID, const Function<void()>& function, WorkQueue* queue)
+        : m_function(function)
+        , m_queue(queue)
+        , m_timerID(timerID)
+    {
+    }
+    ~TimerWorkItem() { }
+
+    Function<void()> function() const { return m_function; }
+    WorkQueue* queue() const { return m_queue; }
+
+    int timerID() const { return m_timerID; }
+
+private:
+    Function<void()> m_function;
+    WorkQueue* m_queue;
+    int m_timerID;
+};
+
+static const int invalidSocketDescriptor = -1;
+static const int threadMessageSize = 1;
+static const char finishThreadMessage[] = "F";
+static const char wakupThreadMessage[] = "W";
+
+void WorkQueue::platformInitialize(const char* name)
+{
+    int fds[2];
+    if (pipe(fds))
+        ASSERT_NOT_REACHED();
+
+    m_readFromPipeDescriptor = fds[0];
+    m_writeToPipeDescriptor = fds[1];
+    FD_ZERO(&m_fileDescriptorSet);
+    FD_SET(m_readFromPipeDescriptor, &m_fileDescriptorSet);
+    m_maxFileDescriptor = m_readFromPipeDescriptor;
+
+    m_socketDescriptor = invalidSocketDescriptor;
+
+    m_threadLoop = true;
+    createThread(reinterpret_cast<WTF::ThreadFunction>(&WorkQueue::workQueueThread), this, name);
+}
+
+void WorkQueue::platformInvalidate()
+{
+    sendMessageToThread(finishThreadMessage);
+}
+
+void WorkQueue::performWork()
+{
+    m_workItemQueueLock.lock();
+
+    while (!m_workItemQueue.isEmpty()) {
+        Vector<Function<void()> > workItemQueue;
+        m_workItemQueue.swap(workItemQueue);
+
+        m_workItemQueueLock.unlock();
+        for (size_t i = 0; i < workItemQueue.size(); ++i)
+            workItemQueue[i]();
+        m_workItemQueueLock.lock();
+    }
+    m_workItemQueueLock.unlock();
+}
+
+void WorkQueue::performFileDescriptorWork()
+{
+    fd_set readFileDescriptorSet = m_fileDescriptorSet;
+
+    if (select(m_maxFileDescriptor + 1, &readFileDescriptorSet, 0, 0, 0) >= 0) {
+        if (FD_ISSET(m_readFromPipeDescriptor, &readFileDescriptorSet)) {
+            char readBuf[threadMessageSize];
+            if (read(m_readFromPipeDescriptor, readBuf, threadMessageSize) == -1)
+                LOG_ERROR("Failed to read from WorkQueueThread pipe");
+            if (!strncmp(readBuf, finishThreadMessage, threadMessageSize))
+                m_threadLoop = false;
+        }
+
+        if (m_socketDescriptor != invalidSocketDescriptor && FD_ISSET(m_socketDescriptor, &readFileDescriptorSet))
+            m_socketEventHandler();
+    }
+}
+
+void WorkQueue::sendMessageToThread(const char* message)
+{
+    if (write(m_writeToPipeDescriptor, message, threadMessageSize) == -1)
+        LOG_ERROR("Failed to wake up WorkQueue Thread");
+}
+
+void* WorkQueue::workQueueThread(WorkQueue* workQueue)
+{
+    while (workQueue->m_threadLoop) {
+        workQueue->performWork();
+        workQueue->performFileDescriptorWork();
+    }
+
+    close(workQueue->m_readFromPipeDescriptor);
+    close(workQueue->m_writeToPipeDescriptor);
+
+    return 0;
+}
+
+void WorkQueue::registerSocketEventHandler(int fileDescriptor, const Function<void()>& function)
+{
+    if (m_socketDescriptor != invalidSocketDescriptor)
+        LOG_ERROR("%d is already registerd.", fileDescriptor);
+
+    m_socketDescriptor = fileDescriptor;
+    m_socketEventHandler = function;
+
+    if (fileDescriptor > m_maxFileDescriptor)
+        m_maxFileDescriptor = fileDescriptor;
+    FD_SET(fileDescriptor, &m_fileDescriptorSet);
+}
+
+void WorkQueue::unregisterSocketEventHandler(int fileDescriptor)
+{
+    m_socketDescriptor = invalidSocketDescriptor;
+
+    if (fileDescriptor == m_maxFileDescriptor)
+        m_maxFileDescriptor = m_readFromPipeDescriptor;
+    FD_CLR(fileDescriptor, &m_fileDescriptorSet);
+}
+
+void WorkQueue::dispatch(const Function<void()>& function)
+{
+    MutexLocker locker(m_workItemQueueLock);
+    m_workItemQueue.append(function);
+    sendMessageToThread(wakupThreadMessage);
+}
+
+bool WorkQueue::timerFired(void* data)
+{
+    TimerWorkItem* item = static_cast<TimerWorkItem*>(data);
+    if (item && item->queue()->m_isValid) {
+        item->queue()->dispatch(item->function());
+        item->queue()->m_timers.take(item->timerID());
+        delete item;
+    }
+
+    return ECORE_CALLBACK_CANCEL;
+}
+
+void WorkQueue::dispatchAfterDelay(const Function<void()>& function, double delay)
+{
+    static int timerId = 0;
+    m_timers.set(timerId, adoptPtr(ecore_timer_add(delay, reinterpret_cast<Ecore_Task_Cb>(timerFired), new TimerWorkItem(timerId, function, this))));
+    timerId++;
+}
index d8a797a..9a1f09b 100644 (file)
@@ -7,7 +7,6 @@ LIST(APPEND WebKit2_LINK_FLAGS
 
 LIST(APPEND WebKit2_SOURCES
     Platform/efl/ModuleEfl.cpp
-    Platform/efl/RunLoopEfl.cpp
     Platform/efl/WorkQueueEfl.cpp
     Platform/unix/SharedMemoryUnix.cpp