DSEventLoop : make DSEventLoop be singelton 11/241711/1
authorSooChan Lim <sc1.lim@samsung.com>
Sun, 2 Aug 2020 07:34:33 +0000 (16:34 +0900)
committerSung-Jin Park <sj76.park@samsung.com>
Thu, 20 Aug 2020 10:05:10 +0000 (19:05 +0900)
Change-Id: I7728a2de0d994db4948dbdb4dbe2ec08dcb9875a

src/DSCompositor/DSCompositor.cpp
src/DSCompositor/DSCompositorPrivate.h
src/DSDisplayArea/DSDisplayArea.cpp
src/DSDisplayArea/DSDisplayAreaPrivate.h
src/DSEventLoop/DSEventLoop.cpp
src/DSEventLoop/DSEventLoop.h
tests/DSEventLoop-test.cpp
tests/libds-mock.h

index 46d87cb..f042897 100644 (file)
@@ -50,7 +50,7 @@ DSCompositorPrivate::DSCompositorPrivate(DSCompositor *p_ptr)
          __canvas(nullptr)
 
 {
-       __eventLoop = std::make_unique<DSEventLoop>();
+       __eventLoop = DSEventLoop::getInstance();
        __wlCompositor = DSWaylandCompositor::getInstance();
        __displayDevice = std::make_unique<DSDisplayDeviceTDMImpl>();
 }
@@ -59,6 +59,7 @@ DSCompositorPrivate::~DSCompositorPrivate()
 {
        DSWaylandCompositor::releaseInstance();
        DSBufferManager::releaseInstance();
+       DSEventLoop::releaseInstance();
 }
 
 bool DSCompositorPrivate::run()
index ada7cf1..e84424c 100644 (file)
@@ -30,7 +30,7 @@ public:
 protected:
 
 private:
-       std::unique_ptr<DSEventLoop> __eventLoop;
+       DSEventLoop *__eventLoop;
        std::unique_ptr<IDSDisplayDevice> __displayDevice;
        DSWaylandCompositor *__wlCompositor;
 
index 1bef4c2..3e92958 100644 (file)
@@ -42,6 +42,7 @@ DSDisplayAreaPrivate::DSDisplayAreaPrivate(DSDisplayArea *p_ptr, std::shared_ptr
          __displayDeviceHWC(nullptr),
          __zone(nullptr),
          __renderEngine(nullptr),
+         __eventLoop(nullptr),
          __x(0),
          __y(0),
          __width(0),
@@ -65,8 +66,11 @@ DSDisplayAreaPrivate::DSDisplayAreaPrivate(DSDisplayArea *p_ptr, std::shared_ptr
        if (!__renderEngine)
                DSLOG_ERR("DSCanvasPrivate", "__RenderEngine is null.");
 
+       __eventLoop = DSEventLoop::getInstance();
+
        // add idle enterer event on __onEventIdleEnterer for rendereing and displaying
-       DSEventLoop::addIdleEnterer(this, __onEventIdleEnterer);
+       // TODO: Remove static function callback. use std::function<> at addIdleEnterer
+       __eventLoop->addIdleEnterer(this, &DSDisplayAreaPrivate::__onEventIdleEnterer);
 
        // The size of DSDisplayArea is the one of DSOutput
        __width = outputImpl->getResolutionWidth();
@@ -74,7 +78,9 @@ DSDisplayAreaPrivate::DSDisplayAreaPrivate(DSDisplayArea *p_ptr, std::shared_ptr
 }
 
 DSDisplayAreaPrivate::~DSDisplayAreaPrivate()
-{}
+{
+       DSEventLoop::releaseInstance();
+}
 
 int DSDisplayAreaPrivate::getWidth()
 {
index b062987..34a4c03 100644 (file)
@@ -39,6 +39,7 @@ private:
        std::shared_ptr<IDSDisplayDeviceHWC> __displayDeviceHWC;
        std::shared_ptr<DSZone> __zone;
        std::shared_ptr<IDSRenderEngine> __renderEngine;
+       DSEventLoop *__eventLoop;
        int __x, __y;
        int __width, __height;
        std::list<std::shared_ptr<DSRenderView>> __renderViewList;
@@ -47,4 +48,4 @@ private:
 
 }
 
-#endif
\ No newline at end of file
+#endif
index 7977f16..1c61db2 100644 (file)
@@ -5,7 +5,7 @@
 namespace display_server
 {
 
-static std::list<Ecore_Idle_Enterer *> __ecoreIdleEntererList;
+//static std::list<Ecore_Idle_Enterer *> __ecoreIdleEntererList;
 
 DSEventLoop::DSEventLoop()
        : __running(false)
@@ -24,6 +24,41 @@ DSEventLoop::~DSEventLoop()
        ecore_shutdown();
 }
 
+DSEventLoop *DSEventLoop::__instance { nullptr };
+std::mutex DSEventLoop::__mutex;
+int DSEventLoop::__refCount { 0 };
+
+DSEventLoop *DSEventLoop::getInstance()
+{
+       std::lock_guard<std::mutex> lock(__mutex);
+
+       if (!__instance) {
+               __instance = new DSEventLoop();
+               if (!__instance) {
+                       DSLOG_ERR("DSEventLoop", "new DSEventLoop() fails.");
+                       return nullptr;
+               }
+               DSLOG_INF("DSEventLoop", "DSEventLoop instance has been created !");
+       }
+
+       ++__refCount;
+
+       return __instance;
+}
+
+void DSEventLoop::releaseInstance()
+{
+       std::lock_guard<std::mutex> lock(__mutex);
+
+       --__refCount;
+       DSLOG_INF("DSEventLoop", "__refCount=%d", __refCount);
+       if (__refCount <= 0) {
+               delete __instance;
+               __instance = nullptr;
+               DSLOG_INF("DSEventLoop", "DSEventLoop instance has been removed !");
+       }
+}
+
 bool DSEventLoop::isRunning()
 {
        return __running;
index 76a8c7a..1645aa9 100644 (file)
@@ -1,8 +1,10 @@
 #ifndef __DS_EVENT_LOOP_H__
 #define __DS_EVENT_LOOP_H__
 
+#include "DSCore.h"
 #include "DSObject.h"
 #include <Ecore.h>
+#include <mutex>
 
 namespace display_server
 {
@@ -10,8 +12,8 @@ namespace display_server
 class DSEventLoop
 {
 public:
-       DSEventLoop();
-       virtual ~DSEventLoop();
+       static DSEventLoop *getInstance();
+       static void releaseInstance();
 
        bool run();
        bool quit();
@@ -19,12 +21,19 @@ public:
        bool isRunning();
 
        // add Ecore_Idle_Enterer
-       // TODO: make generalization, hiding Ecore_Idle_Enterer, Ecore_Task_Cb
-       // TODO: need
-       static void addIdleEnterer(DSObject *slot, Ecore_Task_Cb func);
+       void addIdleEnterer(DSObject *slot, Ecore_Task_Cb func);
 
 private:
+       DSEventLoop(); // private constructor
+       ~DSEventLoop(); // private desctructor
+       DSEventLoop(DSEventLoop &other) = delete; // should not be cloneable
+       void operator=(const DSEventLoop &) = delete; // should not be assignable
+       static DSEventLoop *__instance; // singleton instance
+       static std::mutex __mutex; // mutex
+       static int __refCount;
+
        bool __running;
+       std::list<Ecore_Idle_Enterer *> __ecoreIdleEntererList;
 };
 
 }
index 31d11ea..442c397 100644 (file)
@@ -15,14 +15,14 @@ public:
 
 TEST_F(DSEventLoopTest, NewDSEventLoop)
 {
-       DSEventLoop *eventLoop = new DSEventLoop;
-       delete eventLoop;
-       EXPECT_TRUE(true);
+       DSEventLoop *eventLoop = DSEventLoop::getInstance();
+       EXPECT_TRUE(eventLoop != nullptr);
+       DSEventLoop::releaseInstance();
 }
 
 TEST_F(DSEventLoopTest, RunAndQuit)
 {
-       DSEventLoop eventLoop;
+       DSEventLoop *eventLoop = DSEventLoop::getInstance();
 
        Ecore_Timer *timer = nullptr;
        double delayInSecond = 1.0;
@@ -32,17 +32,19 @@ TEST_F(DSEventLoopTest, RunAndQuit)
                return EINA_FALSE;
        };
 
-       timer = ecore_timer_loop_add(delayInSecond, cb, &eventLoop);
+       timer = ecore_timer_loop_add(delayInSecond, cb, eventLoop);
        EXPECT_TRUE(timer != nullptr);
 
        if (timer != nullptr) {
-               EXPECT_TRUE(eventLoop.run() == true);
+               EXPECT_TRUE(eventLoop->run() == true);
        }
+
+       DSEventLoop::releaseInstance();
 }
 
 TEST_F(DSEventLoopTest, addIdleEnterer)
 {
-       DSEventLoop eventLoop;
+       DSEventLoop *eventLoop = DSEventLoop::getInstance();
 
        Ecore_Timer *timer = nullptr;
        double delayInSecond = 1.0;
@@ -54,15 +56,18 @@ TEST_F(DSEventLoopTest, addIdleEnterer)
 
        auto idleCb = [](void *data) -> Eina_Bool {
                EXPECT_TRUE(true);
+               DSLOG_ERR("soolim", "idleCB");
                return EINA_TRUE;
        };
 
-       timer = ecore_timer_loop_add(delayInSecond, timerCb, &eventLoop);
+       timer = ecore_timer_loop_add(delayInSecond, timerCb, eventLoop);
        EXPECT_TRUE(timer != nullptr);
 
-       DSEventLoop::addIdleEnterer(nullptr, idleCb);
+       eventLoop->addIdleEnterer(nullptr, idleCb);
 
        if (timer != nullptr) {
-               EXPECT_TRUE(eventLoop.run() == true);
+               EXPECT_TRUE(eventLoop->run() == true);
        }
+
+       DSEventLoop::releaseInstance();
 }
index 94a0c04..b15cad4 100644 (file)
@@ -45,6 +45,8 @@ public:
        MockWaylandCompositor()
                : surfaceCreated(false)
        {
+               __eventLoop = DSEventLoop::getInstance();
+
                __waylandCompositor = DSWaylandCompositor::getInstance();
                __waylandCompositor->create();
                __waylandCompositor->registerCallbackSurfaceCreated(this, std::bind(&MockWaylandCompositor::onSurfaceCreated, this, std::placeholders::_1));
@@ -53,6 +55,7 @@ public:
        ~MockWaylandCompositor()
        {
                DSWaylandCompositor::releaseInstance();
+               DSEventLoop::releaseInstance();
        }
 
        void onSurfaceCreated(std::shared_ptr<DSWaylandSurface> waylandSurface)
@@ -68,12 +71,12 @@ public:
 
        void run()
        {
-               __eventLoop.run();
+               __eventLoop->run();
        }
 
        void quit()
        {
-               __eventLoop.quit();
+               __eventLoop->quit();
        }
 
        bool surfaceCreated; // result of surfaceCreated
@@ -82,7 +85,7 @@ public:
 private:
        DSWaylandCompositor *__waylandCompositor;
        std::shared_ptr<DSWaylandSurface> __waylandSurface;
-       DSEventLoop __eventLoop;
+       DSEventLoop *__eventLoop;
 };
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////