From 64edab5b01f61cd97bed9104f3de8cd03ec84f61 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 2 Jun 2022 12:15:10 +0900 Subject: [PATCH] Use source ID instead of GSource To find the GSource properly from the GMainContext, the port object uses the source_id instead of the GSource. And, if creating shared_ptr is failed, the OnEventReceived callback function should return G_SOURCE_REMOVE to prevent recalling the function. Change-Id: I26604a7671f73f1d48476434e180ec4d542c05f2 Signed-off-by: Hwankyu Jhun --- src/port-internal.cc | 35 ++++++++++++++++++++--------------- src/port-internal.hh | 2 +- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/port-internal.cc b/src/port-internal.cc index aba4772..b895d88 100644 --- a/src/port-internal.cc +++ b/src/port-internal.cc @@ -296,17 +296,16 @@ gboolean Port::OnEventReceived(GIOChannel* io, GIOCondition condition, auto port = ptr->lock(); if (port == nullptr) { _E("port is destructed"); - return G_SOURCE_CONTINUE; + return G_SOURCE_REMOVE; } std::lock_guard lock(port->rw_mutex_); - if (port->queue_.empty()) { - port->IgnoreIOEvent(); - return G_SOURCE_CONTINUE; + if (port->source_id_ == 0) { + _E("GSource is destroyed"); + return G_SOURCE_REMOVE; } - if (port->source_ == nullptr || g_source_is_destroyed(port->source_)) { - _E("GSource(%p) is destroyed", port->source_); + if (port->queue_.empty()) { port->IgnoreIOEvent(); return G_SOURCE_CONTINUE; } @@ -327,10 +326,14 @@ void Port::ClearQueue() { void Port::IgnoreIOEvent() { std::lock_guard lock(rw_mutex_); - if (source_ != nullptr && !g_source_is_destroyed(source_)) - g_source_destroy(source_); + if (source_id_ != 0) { + GSource* source = g_main_context_find_source_by_id( + MessageSendingThread::GetInst().GetContext(), source_id_); + if (source != nullptr && !g_source_is_destroyed(source)) + g_source_destroy(source); - source_ = nullptr; + source_id_ = 0; + } if (channel_ != nullptr) { g_io_channel_unref(channel_); @@ -346,22 +349,24 @@ int Port::ListenIOEvent() { return RPC_PORT_ERROR_OUT_OF_MEMORY; } - source_ = g_io_create_watch(channel_, static_cast(G_IO_OUT)); - if (source_ == nullptr) { + GSource* source = g_io_create_watch(channel_, + static_cast(G_IO_OUT)); + if (source == nullptr) { _E("Failed to create GSource"); IgnoreIOEvent(); return RPC_PORT_ERROR_OUT_OF_MEMORY; } auto* ptr = new (std::nothrow) std::weak_ptr(shared_from_this()); - g_source_set_callback(source_, reinterpret_cast(OnEventReceived), + g_source_set_callback(source, reinterpret_cast(OnEventReceived), static_cast(ptr), [](gpointer ptr) { auto* port = static_cast*>(ptr); delete port; }); - g_source_set_priority(source_, G_PRIORITY_DEFAULT); - g_source_attach(source_, MessageSendingThread::GetInst().GetContext()); - g_source_unref(source_); + g_source_set_priority(source, G_PRIORITY_DEFAULT); + source_id_ = g_source_attach(source, + MessageSendingThread::GetInst().GetContext()); + g_source_unref(source); return RPC_PORT_ERROR_NONE; } diff --git a/src/port-internal.hh b/src/port-internal.hh index 8924a8a..f9aba93 100644 --- a/src/port-internal.hh +++ b/src/port-internal.hh @@ -108,7 +108,7 @@ class Port : public std::enable_shared_from_this { std::queue> queue_; int delayed_message_size_ = 0; GIOChannel* channel_ = nullptr; - GSource* source_ = nullptr; + guint source_id_ = 0; }; } // namespace internal -- 2.7.4