From e34e0d98f3da2ca4f9c72e6837156ad4228bf7e2 Mon Sep 17 00:00:00 2001 From: Changgyu Choi Date: Wed, 23 Nov 2022 10:14:42 +0900 Subject: [PATCH 01/16] Release version 1.13.9 Changes: - Add client reset step in OnTimedOut() Change-Id: I70f808c4c1c82902f8e9278f2e8a0044625a5d7c Signed-off-by: Changgyu Choi --- packaging/rpc-port.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/rpc-port.spec b/packaging/rpc-port.spec index 8a0d81a..7d9bdc2 100644 --- a/packaging/rpc-port.spec +++ b/packaging/rpc-port.spec @@ -1,6 +1,6 @@ Name: rpc-port Summary: RPC Port library -Version: 1.13.8 +Version: 1.13.9 Release: 0 Group: Application Framework/Libraries License: Apache-2.0 -- 2.7.4 From 0219f6fc3b16925aee5dad7b5e83ea49e8f64974 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 26 Dec 2022 05:14:37 +0000 Subject: [PATCH 02/16] Call abort() when double free occurs When double free occurs, rpc-port library calls abort(). This is for deubgging C# applications. Change-Id: I15465d756f8b17d21b4b56bb2938cb2c8b536fe4 Signed-off-by: Hwankyu Jhun --- src/rpc-port.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/rpc-port.cc b/src/rpc-port.cc index 6d38540..88799b0 100644 --- a/src/rpc-port.cc +++ b/src/rpc-port.cc @@ -297,6 +297,11 @@ RPC_API int rpc_port_proxy_destroy(rpc_port_proxy_h h) { auto p = static_cast*>(h); auto* proxy = p->get(); + if (proxy->IsDestroying()) { + _E("already destroyed. handle(%p)", proxy); + abort(); + } + _W("rpc_port_proxy_destroy(%p)", proxy); if (getpid() == gettid()) { delete p; @@ -434,6 +439,12 @@ RPC_API int rpc_port_stub_destroy(rpc_port_stub_h h) { _W("rpc_port_stub_destroy(%p)", h); auto p = static_cast<::StubExt*>(h); + if (p->IsDestroying()) { + _E("already destroyed. handle(%p)", h); + abort(); + } + + p->SetDestroying(true); aul_rpc_port_usr_destroy(p->GetPortName().c_str(), rpc_port_get_target_uid()); if (getpid() == gettid()) { delete p; @@ -441,7 +452,6 @@ RPC_API int rpc_port_stub_destroy(rpc_port_stub_h h) { } p->Ignore(); - p->SetDestroying(true); g_idle_add_full(G_PRIORITY_HIGH, [](gpointer data) -> gboolean { auto p = static_cast<::StubExt*>(data); -- 2.7.4 From b581d145bb37721302cad020ebc8cfc729fa1a99 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Mon, 26 Dec 2022 05:28:38 +0000 Subject: [PATCH 03/16] Release version 1.13.10 Changes: - Call abort() when double free occurs Change-Id: I9f7508c7010188f9cdb72200a6539dd620b6ed0a Signed-off-by: Hwankyu Jhun --- packaging/rpc-port.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/rpc-port.spec b/packaging/rpc-port.spec index 7d9bdc2..d5e9ca6 100644 --- a/packaging/rpc-port.spec +++ b/packaging/rpc-port.spec @@ -1,6 +1,6 @@ Name: rpc-port Summary: RPC Port library -Version: 1.13.9 +Version: 1.13.10 Release: 0 Group: Application Framework/Libraries License: Apache-2.0 -- 2.7.4 From 1a65f6984cbf6d874f1413a021938b63cbddcde6 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 4 Jan 2023 03:46:37 +0000 Subject: [PATCH 04/16] Modify connect method of proxy The proxy is able to call the rpc_port_proxy_connect() function after calling the rpc_port_proxy_disconnect() function. Change-Id: Ib9cb6758b1792e4f3413164745b5c34819ef51ce Signed-off-by: Hwankyu Jhun --- src/proxy-internal.cc | 14 ++++++++++---- src/proxy-internal.hh | 1 + 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/proxy-internal.cc b/src/proxy-internal.cc index 518c436..8465ed2 100644 --- a/src/proxy-internal.cc +++ b/src/proxy-internal.cc @@ -197,7 +197,7 @@ int Proxy::Connect(std::string appid, std::string port_name, return RPC_PORT_ERROR_INVALID_PARAMETER; std::lock_guard lock(GetMutex()); - if (listener_ != nullptr) { + if (HasRequested()) { _D("Already requested"); return RPC_PORT_ERROR_INVALID_PARAMETER; } @@ -209,6 +209,7 @@ int Proxy::Connect(std::string appid, std::string port_name, main_port_.reset(); delegate_port_.reset(); + Cancel(); UnsetConnTimer(); int ret = Aul::PrepareStub(real_appid_, port_name_, rpc_port_get_target_uid()); @@ -231,12 +232,12 @@ int Proxy::ConnectSync(std::string appid, std::string port_name, if (listener == nullptr) return RPC_PORT_ERROR_INVALID_PARAMETER; - if (listener_ != nullptr) { - _W("Already requested"); + std::lock_guard lock(GetMutex()); + if (HasRequested()) { + _D("Already requested"); return RPC_PORT_ERROR_INVALID_PARAMETER; } - std::lock_guard lock(GetMutex()); listener_ = listener; target_appid_ = std::move(appid); port_name_ = std::move(port_name); @@ -801,5 +802,10 @@ void Proxy::DestroyWeakPtr(gpointer data) { delete ptr; } +bool Proxy::HasRequested() const { + return listener_ != nullptr && + (!main_port_ || !delegate_port_ || main_port_->GetFd() > 0); +} + } // namespace internal } // namespace rpc_port diff --git a/src/proxy-internal.hh b/src/proxy-internal.hh index 5003539..2cfef0d 100644 --- a/src/proxy-internal.hh +++ b/src/proxy-internal.hh @@ -130,6 +130,7 @@ class Proxy : public std::enable_shared_from_this { std::shared_ptr GetSharedPtr(); gpointer CreateWeakPtr(); static void DestroyWeakPtr(gpointer data); + bool HasRequested() const; private: std::string port_name_; -- 2.7.4 From c8c3a9577b0f30976463a3eba86597fe3e46ff93 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 5 Jan 2023 01:42:10 +0000 Subject: [PATCH 05/16] Release version 1.13.11 Changes: - Modify connect method of proxy Change-Id: I703dd13a99aaaa1bd96bceefcb49e93a8e99f719 Signed-off-by: Hwankyu Jhun --- packaging/rpc-port.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/rpc-port.spec b/packaging/rpc-port.spec index d5e9ca6..d5b8dbc 100644 --- a/packaging/rpc-port.spec +++ b/packaging/rpc-port.spec @@ -1,6 +1,6 @@ Name: rpc-port Summary: RPC Port library -Version: 1.13.10 +Version: 1.13.11 Release: 0 Group: Application Framework/Libraries License: Apache-2.0 -- 2.7.4 From 3698d559b4322fea0153e049552c163c3b594909 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 11 Jan 2023 10:55:05 +0000 Subject: [PATCH 06/16] Use tizen_base::SharedQueue To remove duplicated codes about shared queue, we add a tizen-shared-queue library. This patch uses the tizen_base::SharedQueue and removes duplicated shared queue codes. Change-Id: I43e1aa4ecce2c97524046145b0db02e3cb3e1d0d Signed-off-by: Hwankyu Jhun --- CMakeLists.txt | 1 + packaging/rpc-port.spec | 1 + src/CMakeLists.txt | 1 + src/debug-port-internal.cc | 8 ++--- src/shared-queue-internal.hh | 79 -------------------------------------------- 5 files changed, 7 insertions(+), 83 deletions(-) delete mode 100644 src/shared-queue-internal.hh diff --git a/CMakeLists.txt b/CMakeLists.txt index 4a5a157..33f92a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,7 @@ PKG_CHECK_MODULES(GMOCK_DEPS REQUIRED gmock) PKG_CHECK_MODULES(LIBTZPLATFORM_CONFIG_DEPS REQUIRED libtzplatform-config) PKG_CHECK_MODULES(PARCEL_DEPS REQUIRED parcel) PKG_CHECK_MODULES(PKGMGR_INFO_DEPS REQUIRED pkgmgr-info) +PKG_CHECK_MODULES(TIZEN_SHARED_QUEUE_DEPS REQUIRED tizen-shared-queue) PKG_CHECK_MODULES(UUID_DEPS REQUIRED uuid) ADD_SUBDIRECTORY(src) diff --git a/packaging/rpc-port.spec b/packaging/rpc-port.spec index d5b8dbc..ae8b751 100644 --- a/packaging/rpc-port.spec +++ b/packaging/rpc-port.spec @@ -18,6 +18,7 @@ BuildRequires: pkgconfig(libtzplatform-config) BuildRequires: pkgconfig(parcel) BuildRequires: pkgconfig(pkgmgr) BuildRequires: pkgconfig(pkgmgr-info) +BuildRequires: pkgconfig(tizen-shared-queue) BuildRequires: pkgconfig(uuid) %if 0%{?gcov:1} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1061211..46b286d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -21,6 +21,7 @@ APPLY_PKG_CONFIG(${TARGET_RPC_PORT} PUBLIC LIBTZPLATFORM_CONFIG_DEPS PARCEL_DEPS PKGMGR_INFO_DEPS + TIZEN_SHARED_QUEUE_DEPS UUID_DEPS ) diff --git a/src/debug-port-internal.cc b/src/debug-port-internal.cc index 06e44dc..df51d5b 100644 --- a/src/debug-port-internal.cc +++ b/src/debug-port-internal.cc @@ -33,9 +33,10 @@ #include #include +#include + #include "log-private.hh" #include "port-internal.hh" -#include "shared-queue-internal.hh" namespace rpc_port { namespace internal { @@ -119,7 +120,7 @@ class DebugPortImpl { std::list> sessions_; std::thread thread_; std::atomic is_running_ { false }; - SharedQueue> queue_; + tizen_base::SharedQueue> queue_; mutable std::recursive_mutex mutex_; aul_app_com_connection_h conn_ = nullptr; }; @@ -325,8 +326,7 @@ void DebugPortImpl::CreateThread() { thread_ = std::thread([&]() { _W("START"); do { - std::shared_ptr parcel; - queue_.WaitAndPop(parcel); + std::shared_ptr parcel = queue_.WaitAndPop(); int len = parcel->GetDataSize(); if (len == 0) { _W("Done"); diff --git a/src/shared-queue-internal.hh b/src/shared-queue-internal.hh deleted file mode 100644 index 4cd0d95..0000000 --- a/src/shared-queue-internal.hh +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2020 - 2021 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef SHARED_QUEUE_INTERNAL_HH_ -#define SHARED_QUEUE_INTERNAL_HH_ - -#include -#include -#include -#include - -namespace rpc_port { -namespace internal { - -template -class SharedQueue { - public: - SharedQueue() = default; - virtual ~SharedQueue() = default; - - void Push(T item) { - std::lock_guard lock(mutex_); - queue_.push(item); - cond_var_.notify_one(); - } - - bool TryAndPop(T& item) { - std::lock_guard lock(mutex_); - if (queue_.empty()) - return false; - - item = queue_.front(); - queue_.pop_front(); - - return true; - } - - void WaitAndPop(T& item) { - std::unique_lock lock(mutex_); - while (queue_.empty()) - cond_var_.wait(lock); - - item = queue_.front(); - queue_.pop(); - } - - bool Empty() { - std::lock_guard lock(mutex_); - return queue_.empty(); - } - - int Size() { - std::lock_guard lock(mutex_); - return queue_.size(); - } - - private: - std::queue queue_; - mutable std::mutex mutex_; - std::condition_variable cond_var_; -}; - -} // namespace internal -} // namespace rpc_port - -#endif // SHARED_QUEUE_INTERNAL_HH_ -- 2.7.4 From 43cb14e6408ab07a9e84fe234b99f63ed57a0a67 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 11 Jan 2023 23:26:02 +0000 Subject: [PATCH 07/16] Release version 1.13.12 Changes: - Use tizen_base::SharedQueue Change-Id: I03fac659f314b95277f3552beca0765989ef0870 Signed-off-by: Hwankyu Jhun --- packaging/rpc-port.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/rpc-port.spec b/packaging/rpc-port.spec index ae8b751..6a8a800 100644 --- a/packaging/rpc-port.spec +++ b/packaging/rpc-port.spec @@ -1,6 +1,6 @@ Name: rpc-port Summary: RPC Port library -Version: 1.13.11 +Version: 1.13.12 Release: 0 Group: Application Framework/Libraries License: Apache-2.0 -- 2.7.4 From 95ab7b83df8ffc11a9514ca8209632a868ce41b5 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 18 Jan 2023 06:20:02 +0000 Subject: [PATCH 08/16] Modify Port::Write() method After this patch is applied, if the cache buffer is not empty, the rpc-port library checks the socket whether writing is possible or not. If it's possible, the rpc-port library writes the delayed message to the socket fd. Change-Id: If54967bbc7fce4d4494b9fee44d8dcfe5e57de50 Signed-off-by: Hwankyu Jhun --- src/port-internal.cc | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/src/port-internal.cc b/src/port-internal.cc index b895d88..a937278 100644 --- a/src/port-internal.cc +++ b/src/port-internal.cc @@ -223,19 +223,7 @@ int Port::Write(const void* buf, unsigned int size) { return RPC_PORT_ERROR_NONE; else if (ret == PORT_STATUS_ERROR_IO_ERROR) return RPC_PORT_ERROR_IO_ERROR; - } - - if (delayed_message_size_ > QUEUE_SIZE_MAX) { - _E("cache fail : delayed_message_size (%d), count(%zu)", - delayed_message_size_, queue_.size()); - return RPC_PORT_ERROR_IO_ERROR; - } - - ret = PushDelayedMessage( - std::make_shared(static_cast(buf), - sent_bytes, size)); - - if (CanWrite()) { + } else if (CanWrite()) { while (!queue_.empty()) { int port_status = PopDelayedMessage(); if (port_status != PORT_STATUS_ERROR_NONE) { @@ -247,7 +235,15 @@ int Port::Write(const void* buf, unsigned int size) { } } - return ret; + if (delayed_message_size_ > QUEUE_SIZE_MAX) { + _E("cache fail : delayed_message_size (%d), count(%zu)", + delayed_message_size_, queue_.size()); + return RPC_PORT_ERROR_IO_ERROR; + } + + return PushDelayedMessage( + std::make_shared( + static_cast(buf), sent_bytes, size)); } int Port::Write(const void* buf, unsigned int size, int* sent_bytes) { @@ -299,6 +295,8 @@ gboolean Port::OnEventReceived(GIOChannel* io, GIOCondition condition, return G_SOURCE_REMOVE; } + _W("Writing is now possible. fd: %d, id: %s", + port->GetFd(), port->GetId().c_str()); std::lock_guard lock(port->rw_mutex_); if (port->source_id_ == 0) { _E("GSource is destroyed"); -- 2.7.4 From e0f52c1cd5ca3e92b2249157f770bd6bb858dee3 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 18 Jan 2023 06:43:56 +0000 Subject: [PATCH 09/16] Release version 1.13.13 Changes: - Modify Port::Write() method Change-Id: Ifeb3aab21595f577b57ebae0883f087b8f00a116 Signed-off-by: Hwankyu Jhun --- packaging/rpc-port.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/rpc-port.spec b/packaging/rpc-port.spec index 6a8a800..c533056 100644 --- a/packaging/rpc-port.spec +++ b/packaging/rpc-port.spec @@ -1,6 +1,6 @@ Name: rpc-port Summary: RPC Port library -Version: 1.13.12 +Version: 1.13.13 Release: 0 Group: Application Framework/Libraries License: Apache-2.0 -- 2.7.4 From d234a22cc5bc83726fb5d496ef81851a51c6adad Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 26 Jan 2023 03:39:02 +0000 Subject: [PATCH 10/16] Revert "Check current thread ID to destroy handle" This reverts commit 2da1742b97e33d2b9c42d01104080721143d8b59. When calling the event callback function, app developer releases the handle in the callback function. It makes a crash issue. Even if the destroy function is called in the main thread, the rpc-port library doesn't release the handle immediately to prevent the issue. Change-Id: I58a25d9e4c5f1f42065901dac8e6a30f22f898d2 Signed-off-by: Hwankyu Jhun --- src/rpc-port.cc | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/src/rpc-port.cc b/src/rpc-port.cc index 88799b0..1a09c2c 100644 --- a/src/rpc-port.cc +++ b/src/rpc-port.cc @@ -17,8 +17,6 @@ #include #include #include -#include -#include #include #include @@ -303,13 +301,9 @@ RPC_API int rpc_port_proxy_destroy(rpc_port_proxy_h h) { } _W("rpc_port_proxy_destroy(%p)", proxy); - if (getpid() == gettid()) { - delete p; - return RPC_PORT_ERROR_NONE; - } - proxy->SetDestroying(true); proxy->DisconnectPort(); + g_idle_add_full(G_PRIORITY_HIGH, [](gpointer data) -> gboolean { auto p = static_cast*>(data); @@ -317,7 +311,6 @@ RPC_API int rpc_port_proxy_destroy(rpc_port_proxy_h h) { delete p; return G_SOURCE_REMOVE; }, h, nullptr); - return RPC_PORT_ERROR_NONE; } @@ -446,11 +439,6 @@ RPC_API int rpc_port_stub_destroy(rpc_port_stub_h h) { p->SetDestroying(true); aul_rpc_port_usr_destroy(p->GetPortName().c_str(), rpc_port_get_target_uid()); - if (getpid() == gettid()) { - delete p; - return RPC_PORT_ERROR_NONE; - } - p->Ignore(); g_idle_add_full(G_PRIORITY_HIGH, [](gpointer data) -> gboolean { @@ -459,7 +447,6 @@ RPC_API int rpc_port_stub_destroy(rpc_port_stub_h h) { delete p; return G_SOURCE_REMOVE; }, h, nullptr); - return RPC_PORT_ERROR_NONE; } -- 2.7.4 From 48d325c76040f097b3ce5f036c8ac9298a94ebba Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 26 Jan 2023 04:04:17 +0000 Subject: [PATCH 11/16] Release version 1.13.14 Changes: - Revert "Check current thread ID to destroy handle" Change-Id: I487c8d45b2abefab33204366ab4047c719d72ecf Signed-off-by: Hwankyu Jhun --- packaging/rpc-port.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/rpc-port.spec b/packaging/rpc-port.spec index c533056..1e3e117 100644 --- a/packaging/rpc-port.spec +++ b/packaging/rpc-port.spec @@ -1,6 +1,6 @@ Name: rpc-port Summary: RPC Port library -Version: 1.13.13 +Version: 1.13.14 Release: 0 Group: Application Framework/Libraries License: Apache-2.0 -- 2.7.4 From 8222a5a4242f4efeb750d5a65c74b4732347e3da Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 2 Feb 2023 02:37:06 +0000 Subject: [PATCH 12/16] Move port existence check to the Watch method To make unblocking the main thread, the port existence check is moved to the Watch() method. If the proxy application calls the rpc_port_proxy_connect() function in the sub thread, the Aul::ExistPort() is called in the thread. Change-Id: Ie82e0527c56981337c1b241c8d2b090696a1b0de Signed-off-by: Hwankyu Jhun --- src/proxy-internal.cc | 7 ++++--- src/proxy-internal.hh | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/proxy-internal.cc b/src/proxy-internal.cc index 8465ed2..4a63e3a 100644 --- a/src/proxy-internal.cc +++ b/src/proxy-internal.cc @@ -298,6 +298,9 @@ int Proxy::Watch() { return -1; } + port_exist_ = Aul::ExistPort(real_appid_, port_name_, + rpc_port_get_target_uid()); + SetConnTimer(); SetIdler(); return 0; @@ -476,9 +479,7 @@ gboolean Proxy::OnIdle(gpointer user_data) { DestroyWeakPtr(proxy->idler_data_); proxy->idler_data_ = nullptr; - bool exist = Aul::ExistPort(proxy->real_appid_, proxy->port_name_, - rpc_port_get_target_uid()); - if (exist) { + if (proxy->port_exist_) { proxy->OnPortAppeared(proxy->real_appid_.c_str(), proxy->port_name_.c_str(), -1, proxy.get()); } else { diff --git a/src/proxy-internal.hh b/src/proxy-internal.hh index 2cfef0d..8da58ff 100644 --- a/src/proxy-internal.hh +++ b/src/proxy-internal.hh @@ -146,6 +146,7 @@ class Proxy : public std::enable_shared_from_this { gpointer conn_timer_data_ = nullptr; gpointer idler_data_ = nullptr; mutable std::recursive_mutex mutex_; + bool port_exist_ = false; }; } // namespace internal -- 2.7.4 From 650dcfdb919bae9e3d8ea4a080615fbd30fac566 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Thu, 2 Feb 2023 03:54:03 +0000 Subject: [PATCH 13/16] Release version 1.13.15 Changes: - Move port existence check to the Watch method Change-Id: Ib23c4b1c19e66a9c9aef2a494c3aaf899ccd63f1 Signed-off-by: Hwankyu Jhun --- packaging/rpc-port.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/rpc-port.spec b/packaging/rpc-port.spec index 1e3e117..44eeba5 100644 --- a/packaging/rpc-port.spec +++ b/packaging/rpc-port.spec @@ -1,6 +1,6 @@ Name: rpc-port Summary: RPC Port library -Version: 1.13.14 +Version: 1.13.15 Release: 0 Group: Application Framework/Libraries License: Apache-2.0 -- 2.7.4 From 2530b57722f2ce466145737830e8799af0a3b20d Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 7 Dec 2022 06:06:53 +0000 Subject: [PATCH 14/16] Add a new API for creating parcel handle To create a parcel handle without the header, a new API is added. Adds: - rpc_port_parcel_create_without_header() Change-Id: Ic4d0b79ea580243e988a02261a3c4b586f27bdd4 Signed-off-by: Hwankyu Jhun --- include/rpc-port-parcel.h | 14 ++++++++++++ src/parcel-internal.cc | 39 ++++++++++++++++++++------------- src/parcel-internal.hh | 4 ++-- src/rpc-port-parcel.cc | 15 +++++++++++++ test/unit_tests/rpc_port_parcel_test.cc | 33 +++++++++++++++++++++++++++- 5 files changed, 87 insertions(+), 18 deletions(-) diff --git a/include/rpc-port-parcel.h b/include/rpc-port-parcel.h index 73fdbfe..29cd7df 100644 --- a/include/rpc-port-parcel.h +++ b/include/rpc-port-parcel.h @@ -542,6 +542,20 @@ int rpc_port_parcel_get_raw(rpc_port_parcel_h h, void **raw, unsigned int *size) int rpc_port_parcel_create_from_raw(rpc_port_parcel_h *h, const void *raw, unsigned int size); /** + * @brief Creates the rpc port parcel handle without the header. + * @since_tizen 7.5 + * @remarks You must release @h using rpc_port_parcel_destroy(). + * @param[out] h The rpc port parcel handle + * @return @c 0 on success, + * otherwise a negative error value + * @retval #RPC_PORT_ERROR_NONE Successful + * @retval #RPC_PORT_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #RPC_PORT_ERROR_OUT_OF_MEMORY Out of memory + * @see rpc_port_parcel_destroy() + */ +int rpc_port_parcel_create_without_header(rpc_port_parcel_h *h); + +/** * @} */ diff --git a/src/parcel-internal.cc b/src/parcel-internal.cc index 5cb299d..75f4302 100644 --- a/src/parcel-internal.cc +++ b/src/parcel-internal.cc @@ -22,36 +22,45 @@ namespace rpc_port { namespace internal { -Parcel::Parcel() {} +Parcel::Parcel(bool without_header) + : header_(without_header ? nullptr : new ParcelHeader()) { +} Parcel::~Parcel() {} void Parcel::WriteToParcel(tizen_base::Parcel* parcel) const { - parcel->WriteParcelable(header_); + if (header_.get() != nullptr) { + parcel->WriteParcelable(*header_.get()); + parcel->WriteUInt32(handle_.GetDataSize()); + } - parcel->WriteUInt32(handle_.GetDataSize()); parcel->Write(handle_.GetData(), handle_.GetDataSize()); } void Parcel::ReadFromParcel(tizen_base::Parcel* parcel) { - parcel->ReadParcelable(&header_); + if (header_.get() != nullptr) { + parcel->ReadParcelable(header_.get()); - uint32_t size = 0; - parcel->ReadUInt32(&size); - if (size > 0) { - auto* buf = static_cast(malloc(size)); - if (buf == nullptr) { - _E("Out of memory"); - return; - } + uint32_t size = 0; + parcel->ReadUInt32(&size); + if (size > 0) { + auto* buf = static_cast(malloc(size)); + if (buf == nullptr) { + _E("Out of memory"); + return; + } - parcel->Read(buf, size); - handle_ = std::move(tizen_base::Parcel(buf, size, false)); + parcel->Read(buf, size); + handle_ = std::move(tizen_base::Parcel(buf, size, false)); + } + } else { + handle_ = std::move( + tizen_base::Parcel(parcel->GetData(), parcel->GetDataSize())); } } const ParcelHeader* Parcel::GetParcelHeader() { - return &header_; + return header_.get(); } parcel_h Parcel::GetHandle() const { diff --git a/src/parcel-internal.hh b/src/parcel-internal.hh index 6c907b8..3d0911d 100644 --- a/src/parcel-internal.hh +++ b/src/parcel-internal.hh @@ -31,7 +31,7 @@ namespace internal { class Parcel : public tizen_base::Parcelable { public: - Parcel(); + Parcel(bool without_header = false); ~Parcel(); void WriteToParcel(tizen_base::Parcel* parcel) const override; @@ -44,7 +44,7 @@ class Parcel : public tizen_base::Parcelable { tizen_base::Parcel* GetRawParcel() const; private: - ParcelHeader header_; + std::unique_ptr header_; tizen_base::Parcel handle_; std::unique_ptr raw_parcel_ { nullptr }; }; diff --git a/src/rpc-port-parcel.cc b/src/rpc-port-parcel.cc index 098a53a..e665b5e 100644 --- a/src/rpc-port-parcel.cc +++ b/src/rpc-port-parcel.cc @@ -453,6 +453,9 @@ RPC_API int rpc_port_parcel_get_header(rpc_port_parcel_h h, auto* parcel = static_cast(h); auto* parcel_header = parcel->GetParcelHeader(); + if (parcel_header == nullptr) + return RPC_PORT_ERROR_INVALID_PARAMETER; + *header = reinterpret_cast( const_cast(parcel_header)); return RPC_PORT_ERROR_NONE; @@ -553,3 +556,15 @@ RPC_API int rpc_port_parcel_create_from_raw(rpc_port_parcel_h* h, *h = parcel; return RPC_PORT_ERROR_NONE; } + +RPC_API int rpc_port_parcel_create_without_header(rpc_port_parcel_h* h) { + if (h == nullptr) + return RPC_PORT_ERROR_INVALID_PARAMETER; + + auto* parcel = new (std::nothrow) internal::Parcel(true); + if (parcel == nullptr) + return RPC_PORT_ERROR_OUT_OF_MEMORY; + + *h = static_cast(parcel); + return RPC_PORT_ERROR_NONE; +} diff --git a/test/unit_tests/rpc_port_parcel_test.cc b/test/unit_tests/rpc_port_parcel_test.cc index 63038ca..07de128 100644 --- a/test/unit_tests/rpc_port_parcel_test.cc +++ b/test/unit_tests/rpc_port_parcel_test.cc @@ -524,7 +524,7 @@ TEST_F(ParcelTest, rpc_port_parcel_create_from_raw_P) { } /* - * @testcase rpc_port_parcel_create_from_raw_B + * @testcase rpc_port_parcel_create_from_raw_N * @description Creates the rpc parcel handle with given the raw data. * @apicovered rpc_port_parcel_create_from_raw */ @@ -532,3 +532,34 @@ TEST_F(ParcelTest, rpc_port_parcel_create_from_raw_N) { int ret = rpc_port_parcel_create_from_raw(nullptr, nullptr, 0); ASSERT_EQ(ret, RPC_PORT_ERROR_INVALID_PARAMETER); } + +/* + * @testcase rpc_port_parcel_create_without_header_P + * @description Creates the rpc parcel handle without the header. + * @apicovered rpc_port_parcel_create_without_header + */ +TEST_F(ParcelTest, rpc_port_parcel_create_without_header_P) { + rpc_port_parcel_h parcel = nullptr; + int ret = rpc_port_parcel_create_without_header(&parcel); + ASSERT_EQ(ret, RPC_PORT_ERROR_NONE); + ASSERT_NE(parcel, nullptr); + + std::unique_ptr::type, + decltype(rpc_port_parcel_destroy)*> parcel_auto( + parcel, rpc_port_parcel_destroy); + + rpc_port_parcel_header_h header = nullptr; + ret = rpc_port_parcel_get_header(parcel, &header); + ASSERT_EQ(ret, RPC_PORT_ERROR_INVALID_PARAMETER); + ASSERT_EQ(header, nullptr); +} + +/* + * @testcase rpc_port_parcel_create_without_header_N + * @description Creates the rpc parcel handle without the header. + * @apicovered rpc_port_parcel_create_without_header + */ +TEST_F(ParcelTest, rpc_port_parcel_create_without_header_N) { + int ret = rpc_port_parcel_create_without_header(nullptr); + ASSERT_EQ(ret, RPC_PORT_ERROR_INVALID_PARAMETER); +} -- 2.7.4 From 92b606a086a4d7d40f86e378d64d13bf682d68f9 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Fri, 3 Feb 2023 04:13:59 +0000 Subject: [PATCH 15/16] Release version 1.14.0 Changes: - Add a new API for creating parcel handle Change-Id: I37c8bd60a218fea59dea9c39210187b09878ed90 Signed-off-by: Hwankyu Jhun --- packaging/rpc-port.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packaging/rpc-port.spec b/packaging/rpc-port.spec index 44eeba5..53dd099 100644 --- a/packaging/rpc-port.spec +++ b/packaging/rpc-port.spec @@ -1,6 +1,6 @@ Name: rpc-port Summary: RPC Port library -Version: 1.13.15 +Version: 1.14.0 Release: 0 Group: Application Framework/Libraries License: Apache-2.0 -- 2.7.4 From e578435f79f872c76733351fa3f0d690e629c5f8 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Tue, 21 Feb 2023 01:55:55 +0000 Subject: [PATCH 16/16] Fix wrong API description The '@h' should be '@a h'. Change-Id: I4056ad50e14c7b2a1af775ff6741080463df49a2 Signed-off-by: Hwankyu Jhun --- include/rpc-port-parcel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/rpc-port-parcel.h b/include/rpc-port-parcel.h index 29cd7df..02c5aa3 100644 --- a/include/rpc-port-parcel.h +++ b/include/rpc-port-parcel.h @@ -544,7 +544,7 @@ int rpc_port_parcel_create_from_raw(rpc_port_parcel_h *h, const void *raw, unsig /** * @brief Creates the rpc port parcel handle without the header. * @since_tizen 7.5 - * @remarks You must release @h using rpc_port_parcel_destroy(). + * @remarks You must release @a h using rpc_port_parcel_destroy(). * @param[out] h The rpc port parcel handle * @return @c 0 on success, * otherwise a negative error value -- 2.7.4