From 5ed0c66fd29edadde4bbb0bcc0c92e325e6a5990 Mon Sep 17 00:00:00 2001 From: Boram Bae Date: Wed, 26 Feb 2020 11:32:49 +0900 Subject: [PATCH] Implement add_idle_event at event_loop * This patch also fixe memory leak Change-Id: I070d08a10dd9c02ec6df15602d3a4e37a9618404 Signed-off-by: Boram Bae --- src/server/sensor_listener_proxy.cpp | 2 ++ src/server/server_channel_handler.cpp | 13 +++++++++++ src/shared/channel.cpp | 23 +++++++++---------- src/shared/channel.h | 5 ++++ src/shared/channel_event_handler.cpp | 4 +++- src/shared/event_loop.cpp | 43 +++++++++++++++++++++++++++++------ src/shared/event_loop.h | 2 +- src/shared/ipc_server.cpp | 2 +- 8 files changed, 72 insertions(+), 22 deletions(-) diff --git a/src/server/sensor_listener_proxy.cpp b/src/server/sensor_listener_proxy.cpp index 268158a..8148577 100644 --- a/src/server/sensor_listener_proxy.cpp +++ b/src/server/sensor_listener_proxy.cpp @@ -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(); } diff --git a/src/server/server_channel_handler.cpp b/src/server/server_channel_handler.cpp index 4f8abae..af7db0c 100644 --- a/src/server/server_channel_handler.cpp +++ b/src/server/server_channel_handler.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include "permission_checker.h" #include "application_sensor_handler.h" @@ -40,10 +41,12 @@ std::unordered_map 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) diff --git a/src/shared/channel.cpp b/src/shared/channel.cpp index 7077723..923bc91 100644 --- a/src/shared/channel.cpp +++ b/src/shared/channel.cpp @@ -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(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 msg) diff --git a/src/shared/channel.h b/src/shared/channel.h index 719dca2..bc8444f 100644 --- a/src/shared/channel.h +++ b/src/shared/channel.h @@ -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; diff --git a/src/shared/channel_event_handler.cpp b/src/shared/channel_event_handler.cpp index 9c48c0d..28f3398 100644 --- a/src/shared/channel_event_handler.cpp +++ b/src/shared/channel_event_handler.cpp @@ -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; diff --git a/src/shared/event_loop.cpp b/src/shared/event_loop.cpp index 180b13e..f265d7b 100644 --- a/src/shared/event_loop.cpp +++ b/src/shared/event_loop.cpp @@ -25,6 +25,7 @@ #include #include #include +#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(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; diff --git a/src/shared/event_loop.h b/src/shared/event_loop.h index f785c65..d0d16d1 100644 --- a/src/shared/event_loop.h +++ b/src/shared/event_loop.h @@ -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); diff --git a/src/shared/ipc_server.cpp b/src/shared/ipc_server.cpp index f847c4d..0019bf1 100644 --- a/src/shared/ipc_server.cpp +++ b/src/shared/ipc_server.cpp @@ -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) -- 2.7.4