From fd1c15c4a95a4092008d27583f0c7c3d9ae62f5b Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 28 Sep 2022 10:27:29 +0000 Subject: [PATCH 01/16] Fix bugs about getting and setting raw data Unfortunately, there is a bug about the raw data of the parcel. When the rpc_port_parcel_get_raw() is called, the function allocates a tizen_base::Parcel to set the raw data internally. Change-Id: I4297f7fab5ba144bafd17366b518627bfbd1e5d1 Signed-off-by: Hwankyu Jhun --- src/parcel-internal.cc | 8 ++++++++ src/parcel-internal.hh | 7 ++++++- src/rpc-port-parcel.cc | 26 +++++++++++++++++--------- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/src/parcel-internal.cc b/src/parcel-internal.cc index 75f5805..5cb299d 100644 --- a/src/parcel-internal.cc +++ b/src/parcel-internal.cc @@ -58,5 +58,13 @@ parcel_h Parcel::GetHandle() const { return static_cast(const_cast(&handle_)); } +void Parcel::SetRawParcel(tizen_base::Parcel* raw_parcel) { + raw_parcel_.reset(raw_parcel); +} + +tizen_base::Parcel* Parcel::GetRawParcel() const { + return raw_parcel_.get(); +} + } // namespace internal } // namespace rpc_port diff --git a/src/parcel-internal.hh b/src/parcel-internal.hh index 6922003..6c907b8 100644 --- a/src/parcel-internal.hh +++ b/src/parcel-internal.hh @@ -20,9 +20,10 @@ #include #include - #include +#include + #include "parcel-header-internal.hh" namespace rpc_port { @@ -39,9 +40,13 @@ class Parcel : public tizen_base::Parcelable { const ParcelHeader* GetParcelHeader(); parcel_h GetHandle() const; + void SetRawParcel(tizen_base::Parcel* raw_parcel); + tizen_base::Parcel* GetRawParcel() const; + private: ParcelHeader header_; tizen_base::Parcel handle_; + std::unique_ptr raw_parcel_ { nullptr }; }; } // namespace internal diff --git a/src/rpc-port-parcel.cc b/src/rpc-port-parcel.cc index 86af7b3..12782ee 100644 --- a/src/rpc-port-parcel.cc +++ b/src/rpc-port-parcel.cc @@ -415,9 +415,10 @@ RPC_API int rpc_port_parcel_to_array(rpc_port_parcel_h h, void** array, return RPC_PORT_ERROR_INVALID_PARAMETER; auto* parcel = static_cast(h); - void* raw = nullptr; - uint32_t raw_size = 0; - parcel_get_raw(parcel->GetHandle(), &raw, &raw_size); + tizen_base::Parcel raw_parcel; + raw_parcel.WriteParcelable(*parcel); + void* raw = raw_parcel.GetData(); + uint32_t raw_size = raw_parcel.GetDataSize();; if (raw_size == 0) { _E("raw_size is zero"); return RPC_PORT_ERROR_IO_ERROR; @@ -440,7 +441,8 @@ RPC_API int rpc_port_parcel_from_array(rpc_port_parcel_h h, const void* array, auto* parcel = static_cast(h); uint32_t valid_size = size & UINT32_MAX; - parcel_reset(parcel->GetHandle(), array, valid_size); + tizen_base::Parcel raw_parcel(array, valid_size); + raw_parcel.ReadParcelable(parcel); return RPC_PORT_ERROR_NONE; } @@ -517,12 +519,18 @@ RPC_API int rpc_port_parcel_get_raw(rpc_port_parcel_h h, void** raw, return RPC_PORT_ERROR_INVALID_PARAMETER; auto* parcel = static_cast(h); - void* raw_data = nullptr; - uint32_t raw_size = 0; - parcel_get_raw(parcel->GetHandle(), &raw_data, &raw_size); + auto* raw_parcel = new (std::nothrow) tizen_base::Parcel(); + if (raw_parcel != nullptr) { + raw_parcel->WriteParcelable(*parcel); + parcel->SetRawParcel(raw_parcel); + *raw = raw_parcel->GetData(); + *size = static_cast(raw_parcel->GetDataSize()); + } else { + _E("Out of memory"); + *raw = nullptr; + *size = 0; + } - *raw = raw_data; - *size = static_cast(raw_size); return RPC_PORT_ERROR_NONE; } -- 2.7.4 From 04fa14c796d9d939647ceb149a5f70b8f6d2cb79 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 28 Sep 2022 23:20:50 +0000 Subject: [PATCH 02/16] Release version 1.13.7 Changes: - Fix bugs about getting and setting raw data Change-Id: I55f35f2f2506158285f6b3f07ac8a924e73e6206 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 650f8b2..19ef7b9 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.6 +Version: 1.13.7 Release: 0 Group: Application Framework/Libraries License: Apache-2.0 -- 2.7.4 From 98c79873c97089db94449b57c2603dc43f0bef14 Mon Sep 17 00:00:00 2001 From: Changgyu Choi Date: Tue, 4 Oct 2022 11:47:34 +0900 Subject: [PATCH 03/16] Fix wrong exception handling Change-Id: Ifd4f0104ad69dbcaddbdc31a75e84b676471716e Signed-off-by: Changgyu Choi --- benchmark/server/main.cc | 21 +++++++++--------- benchmark/tool/main.cc | 58 ++++++++++++++++++++++++++---------------------- 2 files changed, 42 insertions(+), 37 deletions(-) diff --git a/benchmark/server/main.cc b/benchmark/server/main.cc index c4466cf..9be81a1 100644 --- a/benchmark/server/main.cc +++ b/benchmark/server/main.cc @@ -29,14 +29,14 @@ namespace bs = rpc_port::BenchmarkStub::stub; class TestService : public bs::Benchmark::ServiceBase { public: class Factory : public bs::Benchmark::ServiceBase::Factory { - public: - virtual ~Factory() = default; - - std::unique_ptr - CreateService(std::string sender, std::string instance) { - return std::unique_ptr( - new TestService(sender, instance)); - } + public: + virtual ~Factory() = default; + + std::unique_ptr + CreateService(std::string sender, std::string instance) { + return std::unique_ptr( + new TestService(sender, instance)); + } }; TestService(std::string sender, std::string instance) : @@ -75,9 +75,10 @@ class MainLoop { try { stub_.Listen(std::shared_ptr( new TestService::Factory())); - } catch (const std::exception& e) { - _E("stub listen is failed(%s)", e.what()); + } catch (const bs::Exception&) { + _E("stub listen is failed"); } + g_main_loop_run(loop_); } diff --git a/benchmark/tool/main.cc b/benchmark/tool/main.cc index 580eb69..8abe412 100644 --- a/benchmark/tool/main.cc +++ b/benchmark/tool/main.cc @@ -65,8 +65,8 @@ class Tester { void Run(int argc, char** argv) { options_ = rpc_port::benchmark::Options::Parse(argc, argv); if (!options_) { - _E("options is nullptr"); - exit(1); + std::cerr << "options is unllptr" << std::endl; + return; } ExecuteServer(); @@ -75,28 +75,36 @@ class Tester { try { proxy_->Connect(true); } catch (const bp::Exception& e) { - _E("Connect() failed"); - exit(1); + std::cerr << "Connect() failed" << std::endl; + return; + } catch (const std::exception& e) { + std::cerr << "Connect() failed. " << e.what() << std::endl; + return; } printf("%15s\t%15s\t%15s\t\t%15s\t\t%15s\n", "Iterations", "Data size", "Time", "Throughput", "Latency"); - if (options_->IsAll()) { - DoTest(4000, 10); - DoTest(4000, 20); - DoTest(4000, 100); - DoTest(4000, 200); - DoTest(2000, 1000); - DoTest(2000, 2000); - DoTest(1000, 10000); - DoTest(1000, 20000); - DoTest(1000, 30000); - DoTest(1000, 40000); - DoTest(1000, 50000); - DoTest(1000, 60000); - DoTest(500, 100000); - } else { - DoTest(options_->GetIters(), options_->GetSize()); + + try { + if (options_->IsAll()) { + DoTest(4000, 10); + DoTest(4000, 20); + DoTest(4000, 100); + DoTest(4000, 200); + DoTest(2000, 1000); + DoTest(2000, 2000); + DoTest(1000, 10000); + DoTest(1000, 20000); + DoTest(1000, 30000); + DoTest(1000, 40000); + DoTest(1000, 50000); + DoTest(1000, 60000); + DoTest(500, 100000); + } else { + DoTest(options_->GetIters(), options_->GetSize()); + } + } catch (const bp::Exception& e) { + std::cerr << "test failed" << std::endl; } } @@ -134,7 +142,8 @@ class Tester { } void EndTime(int iters, int size) { - std::chrono::duration sec = std::chrono::system_clock::now() - start_; + std::chrono::duration sec = + std::chrono::system_clock::now() - start_; double t = size * iters * 8 / sec.count() / 1024 / 1024; double l = sec.count() * 1000 / iters; @@ -175,11 +184,6 @@ class Tester { int main(int argc, char** argv) { Tester tester; - try { - tester.Run(argc, argv); - } catch (const std::exception& e) { - std::cerr << "Exception occurred!!!" << e.what() << std::endl; - } - + tester.Run(argc, argv); return 0; } -- 2.7.4 From b3ad5d660c267deb2276dc43d8a95bb5ed0cfcc6 Mon Sep 17 00:00:00 2001 From: Hwankyu Jhun Date: Wed, 12 Oct 2022 06:41:39 +0000 Subject: [PATCH 04/16] Release the client handle When the client application calls the rpc_port_proxy_connect() function after the diconnected event is received, the main_client_ and the delegate_client_ handles have to be released. Change-Id: I2aeef18323bc9f438b048cfef42fb9dd1c82f62e Signed-off-by: Hwankyu Jhun --- src/proxy-internal.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/proxy-internal.cc b/src/proxy-internal.cc index 8ddb569..7816276 100644 --- a/src/proxy-internal.cc +++ b/src/proxy-internal.cc @@ -206,6 +206,8 @@ int Proxy::Connect(std::string appid, std::string port_name, target_appid_ = std::move(appid); port_name_ = std::move(port_name); SetRealAppId(target_appid_); + main_port_.reset(); + delegate_port_.reset(); UnsetConnTimer(); int ret = Aul::PrepareStub(real_appid_, port_name_, -- 2.7.4 From 2ef2bea64aa235d172daaefc5e5776d6b4f51288 Mon Sep 17 00:00:00 2001 From: Changgyu Choi Date: Mon, 17 Oct 2022 13:14:44 +0900 Subject: [PATCH 05/16] Fix static analysis issues Change-Id: I443f2472f98001c1b279cc27d835dc341024e846 Signed-off-by: Changgyu Choi --- src/client-socket-internal.cc | 8 ++++---- src/peer-cred-internal.cc | 2 +- src/rpc-port-parcel.cc | 4 ++-- src/server-socket-internal.cc | 2 +- utils/debug-port.cc | 4 ++-- utils/message.cc | 3 ++- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/client-socket-internal.cc b/src/client-socket-internal.cc index 4fbb344..c932342 100644 --- a/src/client-socket-internal.cc +++ b/src/client-socket-internal.cc @@ -62,7 +62,7 @@ int ClientSocket::Connect(const std::string& endpoint) { snprintf(sockaddr.sun_path, sizeof(sockaddr.sun_path), "%s", endpoint.c_str()); struct sockaddr* sockaddr_ptr = reinterpret_cast(&sockaddr); - socklen_t len = sizeof(sockaddr); + socklen_t len = static_cast(sizeof(sockaddr)); int ret = connect(GetFd(), sockaddr_ptr, len); fcntl(GetFd(), F_SETFL, flag); if (ret < 0) { @@ -142,7 +142,7 @@ int ClientSocket::GetSendBufferSize() { int ClientSocket::GetReceiveTimeout() { struct timeval timeout = { 0, }; - socklen_t len = sizeof(struct timeval); + socklen_t len = static_cast(sizeof(struct timeval)); int ret = getsockopt(GetFd(), SOL_SOCKET, SO_RCVTIMEO, reinterpret_cast(&timeout), &len); if (ret < 0) { @@ -156,7 +156,7 @@ int ClientSocket::GetReceiveTimeout() { } void ClientSocket::SetReceiveBufferSize(int size) { - socklen_t len = sizeof(size); + socklen_t len = static_cast(sizeof(size)); int ret = setsockopt(GetFd(), SOL_SOCKET, SO_RCVBUF, &size, len); if (ret < 0) { ret = -errno; @@ -191,7 +191,7 @@ void ClientSocket::SetReceiveTimeout(int timeout) { .tv_sec = static_cast(timeout / 1000), .tv_usec = static_cast((timeout % 1000) * 1000) }; - socklen_t len = sizeof(struct timeval); + socklen_t len = static_cast(sizeof(struct timeval)); int ret = setsockopt(GetFd(), SOL_SOCKET, SO_RCVTIMEO, &tv, len); if (ret < 0) { ret = -errno; diff --git a/src/peer-cred-internal.cc b/src/peer-cred-internal.cc index eebc131..e978e0f 100644 --- a/src/peer-cred-internal.cc +++ b/src/peer-cred-internal.cc @@ -31,7 +31,7 @@ PeerCred::PeerCred(pid_t pid, uid_t uid, gid_t gid) PeerCred* PeerCred::Get(int fd) { struct ucred cred; - socklen_t len = sizeof(struct ucred); + socklen_t len = static_cast(sizeof(struct ucred)); int ret = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, static_cast(&cred), &len); if (ret != 0) { diff --git a/src/rpc-port-parcel.cc b/src/rpc-port-parcel.cc index 12782ee..098a53a 100644 --- a/src/rpc-port-parcel.cc +++ b/src/rpc-port-parcel.cc @@ -96,7 +96,7 @@ RPC_API int rpc_port_parcel_send(rpc_port_parcel_h h, rpc_port_h port) { tizen_base::Parcel raw_parcel; raw_parcel.WriteParcelable(*parcel); void* raw = reinterpret_cast(raw_parcel.GetData()); - uint32_t len = raw_parcel.GetDataSize(); + uint32_t len = static_cast(raw_parcel.GetDataSize()); if (len <= 0) return RPC_PORT_ERROR_INVALID_PARAMETER; @@ -418,7 +418,7 @@ RPC_API int rpc_port_parcel_to_array(rpc_port_parcel_h h, void** array, tizen_base::Parcel raw_parcel; raw_parcel.WriteParcelable(*parcel); void* raw = raw_parcel.GetData(); - uint32_t raw_size = raw_parcel.GetDataSize();; + size_t raw_size = raw_parcel.GetDataSize(); if (raw_size == 0) { _E("raw_size is zero"); return RPC_PORT_ERROR_IO_ERROR; diff --git a/src/server-socket-internal.cc b/src/server-socket-internal.cc index 228e75b..4f60c20 100644 --- a/src/server-socket-internal.cc +++ b/src/server-socket-internal.cc @@ -42,7 +42,7 @@ bool ServerSocket::IsClosed() { ClientSocket* ServerSocket::Accept() { struct sockaddr_un addr = { 0, }; - socklen_t len = sizeof(struct sockaddr_un); + socklen_t len = static_cast(sizeof(struct sockaddr_un)); auto* addr_ptr = reinterpret_cast(&addr); int client_fd = accept(GetFd(), addr_ptr, &len); if (client_fd == -1) { diff --git a/utils/debug-port.cc b/utils/debug-port.cc index b1c5fc7..08a80ea 100644 --- a/utils/debug-port.cc +++ b/utils/debug-port.cc @@ -219,7 +219,7 @@ void DebugPort::Unwatch() { int DebugPort::Accept(struct ucred* cred) { struct sockaddr_un addr = { 0, }; - socklen_t socklen = sizeof(addr); + socklen_t socklen = static_cast(sizeof(addr)); int client_fd = accept(fd_, reinterpret_cast(&addr), &socklen); if (client_fd < 0) { @@ -227,7 +227,7 @@ int DebugPort::Accept(struct ucred* cred) { return -1; } - socklen = sizeof(struct ucred); + socklen = static_cast(sizeof(struct ucred)); int ret = getsockopt(client_fd, SOL_SOCKET, SO_PEERCRED, cred, &socklen); if (ret < 0) { diff --git a/utils/message.cc b/utils/message.cc index c4145bc..e62bd3e 100644 --- a/utils/message.cc +++ b/utils/message.cc @@ -69,7 +69,8 @@ void Message::Hexdump() { break; std::cout << std::setw(8) << address; - nread = ((data_.size() - address) > 16) ? 16 : (data_.size() - address); + nread = static_cast( + ((data_.size() - address) > 16) ? 16 : (data_.size() - address)); for (unsigned int i = 0; i < 16; ++i) { if (i % 8 == 0) -- 2.7.4 From fb67889685490cc8b304bb21205b71f4db817d01 Mon Sep 17 00:00:00 2001 From: Changgyu Choi Date: Tue, 18 Oct 2022 11:25:12 +0900 Subject: [PATCH 06/16] Release version 1.13.8 Changes: - Fix wrong exception handling - Release the client handle - Fix static analysis issues Change-Id: Ia6118104adb388f2a6387b8f5ad0295949df1402 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 19ef7b9..8a0d81a 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.7 +Version: 1.13.8 Release: 0 Group: Application Framework/Libraries License: Apache-2.0 -- 2.7.4 From bf7ec8b46ea1e854256c01faf3f1e9f7ec1e8749 Mon Sep 17 00:00:00 2001 From: Changgyu Choi Date: Tue, 22 Nov 2022 14:29:40 +0900 Subject: [PATCH 07/16] Add client reset step in OnTimedOut() If the timeout occurs between OnAppeared and Connected events, even if try to reconnect, the port may not be valid. After applying this patch, the client is reset to protect the possibility of accessing invalid ports. Change-Id: Ic268bac9f899f96c2ceda196f5def1abdd624159 Signed-off-by: Changgyu Choi --- src/proxy-internal.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/proxy-internal.cc b/src/proxy-internal.cc index 7816276..518c436 100644 --- a/src/proxy-internal.cc +++ b/src/proxy-internal.cc @@ -442,6 +442,8 @@ gboolean Proxy::OnTimedOut(gpointer user_data) { } proxy->Cancel(); + proxy->main_client_.reset(); + proxy->delegate_client_.reset(); DestroyWeakPtr(proxy->conn_timer_data_); proxy->conn_timer_data_ = nullptr; -- 2.7.4 From e34e0d98f3da2ca4f9c72e6837156ad4228bf7e2 Mon Sep 17 00:00:00 2001 From: Changgyu Choi Date: Wed, 23 Nov 2022 10:14:42 +0900 Subject: [PATCH 08/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 09/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 10/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 11/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 12/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 13/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 14/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 15/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 16/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