Implement add_idle_event at event_loop 64/225964/1 accepted/tizen/5.5/unified/20200228.124203 submit/tizen_5.5/20200227.012111
authorBoram Bae <boram21.bae@samsung.com>
Wed, 26 Feb 2020 02:32:49 +0000 (11:32 +0900)
committerBoram Bae <boram21.bae@samsung.com>
Wed, 26 Feb 2020 02:32:49 +0000 (11:32 +0900)
* This patch also fixe memory leak

Change-Id: I070d08a10dd9c02ec6df15602d3a4e37a9618404
Signed-off-by: Boram Bae <boram21.bae@samsung.com>
src/server/sensor_listener_proxy.cpp
src/server/server_channel_handler.cpp
src/shared/channel.cpp
src/shared/channel.h
src/shared/channel_event_handler.cpp
src/shared/event_loop.cpp
src/shared/event_loop.h
src/shared/ipc_server.cpp

index 268158a..8148577 100644 (file)
@@ -43,11 +43,13 @@ sensor_listener_proxy::sensor_listener_proxy(uint32_t id,
 , m_last_accuracy(SENSOR_ACCURACY_UNDEFINED)
 , m_need_to_notify_attribute_changed(false)
 {
+       _D("Create [%p][%s]", this, m_uri.data());
        sensor_policy_monitor::get_instance().add_listener(this);
 }
 
 sensor_listener_proxy::~sensor_listener_proxy()
 {
+       _D("Delete [%p][%s]", this, m_uri.data());
        sensor_policy_monitor::get_instance().remove_listener(this);
        stop();
 }
index 4f8abae..af7db0c 100644 (file)
@@ -25,6 +25,7 @@
 #include <sensor_utils.h>
 #include <sensor_types_private.h>
 #include <command_types.h>
+#include <event_loop.h>
 
 #include "permission_checker.h"
 #include "application_sensor_handler.h"
@@ -40,10 +41,12 @@ std::unordered_map<ipc::channel *, application_sensor_handler *> server_channel_
 server_channel_handler::server_channel_handler(sensor_manager *manager)
 : m_manager(manager)
 {
+       _I("Create[%p]", this);
 }
 
 server_channel_handler::~server_channel_handler()
 {
+       _I("Destroy[%p]", this);
 }
 
 void server_channel_handler::connected(channel *ch)
@@ -52,6 +55,7 @@ void server_channel_handler::connected(channel *ch)
 
 void server_channel_handler::disconnected(channel *ch)
 {
+       _I("Disconnect[%p] using channel[%p]", this, ch);
        m_manager->deregister_channel(ch);
 
        auto it_asensor = m_app_sensors.find(ch);
@@ -72,6 +76,15 @@ void server_channel_handler::disconnected(channel *ch)
                m_listeners.erase(it_listener->second);
                m_listener_ids.erase(ch);
        }
+
+       if (ch->loop()) {
+               ch->loop()->add_idle_event(0, [](size_t, void* data) {
+                       channel* ch = (channel*)data;
+                       delete ch;
+               },  ch);
+       } else {
+               _D("Should not be here : channel[%p]", ch);
+       }
 }
 
 void server_channel_handler::read(channel *ch, message &msg)
index 7077723..923bc91 100644 (file)
@@ -110,12 +110,12 @@ channel::channel(socket *sock)
 , m_loop(NULL)
 , m_connected(false)
 {
-       _D("Created");
+       _D("Create[%p]", this);
 }
 
 channel::~channel()
 {
-       _D("Destroyed[%llu]", m_event_id);
+       _D("Destroy[%p]", this);
        if (is_connected()) {
                disconnect();
        }
@@ -128,7 +128,7 @@ uint64_t channel::bind(void)
                        (EVENT_IN | EVENT_HUP | EVENT_NVAL),
                        dynamic_cast<channel_event_handler *>(m_handler));
 
-       _D("Bound[%llu]", m_event_id);
+       _D("Bind channel[%p] : handler[%p] event_id[%llu]", this, m_handler, m_event_id);
        return m_event_id;
 }
 
@@ -154,7 +154,7 @@ uint64_t channel::connect(channel_handler *handler, event_loop *loop, bool loop_
 
        bind(handler, loop, loop_bind);
 
-       _D("Connected[%llu]", m_event_id);
+       _D("Connect channel[%p] : event id[%llu]", this, m_event_id);
        return m_event_id;
 }
 
@@ -162,37 +162,36 @@ void channel::disconnect(void)
 {
        AUTOLOCK(m_cmutex);
        if (!is_connected()) {
-               _D("Channel is not connected");
+               _D("Channel[%p] is not connected", this);
                return;
        }
 
        m_connected.store(false);
 
-       _D("Disconnecting..[%llu]", m_event_id);
+       _D("Disconnect channel[%p]", this);
 
        if (m_handler) {
+               _D("Disconnect channel[%p] handler[%p]", this, m_handler);
                m_handler->disconnected(this);
                m_handler = NULL;
        }
 
        if (m_loop) {
                for(auto id : m_pending_event_id) {
-                       _D("Remove pending event id[%llu]", id);
+                       _D("Remove channel[%p] pending event id[%llu]", this, id);
                        m_loop->remove_event(id, true);
                }
-               _D("Remove event[%llu]", m_event_id);
+               _D("Remove channel[%p] event[%llu]",this, m_event_id);
                m_loop->remove_event(m_event_id, true);
-               m_loop = NULL;
                m_event_id = 0;
        }
 
        if (m_socket) {
-               _D("Release socket[%d]", m_socket->get_fd());
+               _D("Release channel[%p] socket[%d]", this, m_socket->get_fd());
                delete m_socket;
                m_socket = NULL;
        }
-
-       _D("Disconnected");
+       _D("Channel[%p] is disconnected");
 }
 
 bool channel::send(std::shared_ptr<message> msg)
index 719dca2..bc8444f 100644 (file)
@@ -60,6 +60,11 @@ public:
        int get_fd(void) const;
        void remove_pending_event_id(uint64_t id);
 
+       event_loop *loop()
+       {
+               return m_loop;
+       }
+
 private:
        int m_fd;
        uint64_t m_event_id;
index 9c48c0d..28f3398 100644 (file)
@@ -29,10 +29,12 @@ channel_event_handler::channel_event_handler(channel *ch, channel_handler *handl
 : m_ch(ch)
 , m_handler(handler)
 {
+       _D("Create[%p]", this);
 }
 
 channel_event_handler::~channel_event_handler()
 {
+       _D("Destroy[%p]", this);
        m_ch = NULL;
        m_handler = NULL;
 }
@@ -45,7 +47,7 @@ bool channel_event_handler::handle(int fd, event_condition condition)
                return false;
 
        if (condition & (EVENT_HUP)) {
-               _D("The other proccess is dead");
+               _D("Disconnect[%p] : The other proccess is dead", this);
                m_ch->disconnect();
                m_ch = NULL;
                return false;
index 180b13e..f265d7b 100644 (file)
@@ -25,6 +25,7 @@
 #include <time.h>
 #include <sys/eventfd.h>
 #include <glib.h>
+#include "channel_event_handler.h"
 
 #include "sensor_log.h"
 #include "event_handler.h"
@@ -58,16 +59,16 @@ static gboolean g_io_handler(GIOChannel *ch, GIOCondition condition, gpointer da
        term = loop->is_terminator(fd);
 
        if (cond & G_IO_NVAL)
-               return FALSE;
+               return G_SOURCE_REMOVE;
 
        ret = handler->handle(fd, (event_condition)cond);
 
        if (!ret && !term) {
                loop->remove_event(id);
-               return FALSE;
+               return G_SOURCE_REMOVE;
        }
 
-       return TRUE;
+       return G_SOURCE_CONTINUE;
 }
 
 static gint on_timer(gpointer data)
@@ -146,7 +147,12 @@ uint64_t event_loop::add_event(const int fd, const event_condition cond, event_h
        return id;
 }
 
-uint64_t event_loop::add_idle_event(unsigned int priority, idle_handler *handler)
+struct idler_data {
+       void (*m_fn)(size_t, void*);
+       void* m_data;
+};
+
+size_t event_loop::add_idle_event(unsigned int priority, void (*fn)(size_t, void*), void* data)
 {
        GSource *src;
 
@@ -156,10 +162,21 @@ uint64_t event_loop::add_idle_event(unsigned int priority, idle_handler *handler
        src = g_idle_source_new();
        retvm_if(!src, 0, "Failed to allocate memory");
 
+       idler_data *id = new idler_data();
+       id->m_fn = fn;
+       id->m_data = data;
+
+       g_source_set_callback(src, [](gpointer data) -> gboolean {
+               idler_data *id = (idler_data *)data;
+               id->m_fn((size_t)id, id->m_data);
+               delete id;
+               return G_SOURCE_REMOVE;
+       }, id, NULL);
+
+       g_source_attach(src, g_main_loop_get_context (m_mainloop));
        g_source_unref(src);
 
-       /* Not Supported yet */
-       return 0;
+       return (size_t)id;
 }
 
 bool event_loop::remove_event(uint64_t id, bool close_channel)
@@ -195,9 +212,21 @@ void event_loop::release_info(handler_info *info)
        g_source_unref(info->g_src);
 
        g_io_channel_unref(info->g_ch);
+
        info->g_ch = NULL;
+       channel_event_handler *ce_handler = nullptr;
+       ce_handler = dynamic_cast<channel_event_handler *>(info->handler);
+       if (ce_handler) {
+               _D("Add idle event for lazy release : handler[%p]", ce_handler);
+               add_idle_event(0, [](size_t, void *data) {
+                       channel_event_handler *handler = (channel_event_handler *)data;
+                       delete handler;
+               }, ce_handler);
+       } else {
+               _D("Release handler[%p]", info->handler);
+               delete info->handler;
+       }
 
-       delete info->handler;
        info->handler = NULL;
 
        delete info;
index f785c65..d0d16d1 100644 (file)
@@ -75,7 +75,7 @@ public:
        void set_mainloop(GMainLoop *mainloop);
 
        uint64_t add_event(const int fd, const event_condition cond, event_handler *handler);
-       uint64_t add_idle_event(unsigned int priority, idle_handler *handler);
+       size_t add_idle_event(unsigned int priority, void (*fn)(size_t, void*), void* data);
 
        bool remove_event(uint64_t id, bool close_channel = false);
        void remove_all_events(void);
index f847c4d..0019bf1 100644 (file)
@@ -84,7 +84,7 @@ void ipc_server::register_channel(int fd, channel *ch)
        if (id == 0)
                delete ev_handler;
 
-       _D("Registered event[%llu]", id);
+       _D("Register channel[%p] : event_id[%llu]", ch, id);
 }
 
 void ipc_server::register_acceptor(void)