1 // Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache-2.0 license that can be
3 // found in the LICENSE file.
5 #include "pkginfo_client.hh"
7 #include <cpu-boosting.h>
16 #include "parcelable_factory.hh"
17 #include "system_locale.hh"
18 #include "ready_checker.hh"
19 #include "utils/logging.hh"
21 #include "pkgmgrinfo_debug.h"
22 #include "pkgmgrinfo_private.h"
24 #define LIBPKGMGR_INFO LIB_PATH "/libpkgmgr-info-server.so.0"
25 #define DIRECT_ACCESS_FUNC "_request_handler_direct_access"
27 namespace pkgmgr_client {
29 constexpr const char SOCK_PATH[] = "/run/pkgmgr-info-server";
30 constexpr const char SERVER_READY[] = "/run/.pkginfo_server_ready";
31 constexpr const char DEST_PROCESS_NAME[] = "pkgmgr-info";
33 PkgInfoClient::CPUInheritanceInvoker::CPUInheritanceInvoker()
34 : set_complete_(false) {}
36 PkgInfoClient::CPUInheritanceInvoker::~CPUInheritanceInvoker() {
37 ClearCPUInheritance();
40 void PkgInfoClient::CPUInheritanceInvoker::SetCPUInheritance() {
41 int ret = resource_set_cpu_inheritance(gettid(), DEST_PROCESS_NAME, -1);
43 LOG(ERROR) << "set cpu inheritance fail ret : " << ret;
50 void PkgInfoClient::CPUInheritanceInvoker::ClearCPUInheritance() {
54 int ret = resource_clear_cpu_inheritance(gettid(), DEST_PROCESS_NAME);
56 LOG(ERROR) << "clear cpu inheritance fail ret : " << ret;
60 set_complete_ = false;
63 PkgInfoClient::PkgInfoClient(
64 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable> parcel,
65 uid_t uid, pkgmgr_common::ReqType req_type)
67 result_parcel_(nullptr),
71 socket_ = std::make_unique<pkgmgr_common::socket::ClientSocket>(SOCK_PATH);
74 bool PkgInfoClient::SendRequest() {
75 static pkgmgr_common::ReadyChecker check_server(SERVER_READY);
76 if (socket_ == nullptr) {
77 LOG(ERROR) << "Socket is not ready";
82 p.WriteParcelable(*parcel_.get());
84 // CREATE_DB request type need to be executed directly by the caller
85 if (req_type_ == pkgmgr_common::ReqType::CREATE_DB) {
87 return RequestHandlerDirectAccess(&p);
90 if (!check_server.IsReady()) {
91 LOG(WARNING) << "Server is not ready, try to direct access"
92 ", Request type: " << pkgmgr_common::ReqTypeToString(req_type_);
94 return RequestHandlerDirectAccess(&p);
97 LOG(WARNING) << "Try to send request, Request type: "
98 << pkgmgr_common::ReqTypeToString(req_type_);
100 cpu_inheritance_invoker_.SetCPUInheritance();
101 if (!socket_->Connect(req_type_)) {
102 LOG(ERROR) << "Failed to connect client socket, try to direct access"
103 ", Request type: " << pkgmgr_common::ReqTypeToString(req_type_);
105 return RequestHandlerDirectAccess(&p);
108 if (socket_->SendData(&req_type_, sizeof(req_type_)) != 0) {
109 LOG(ERROR) << "fail to send data";
113 pid_t tid = gettid();
114 if (socket_->SendData(&tid, sizeof(tid)) != 0) {
115 LOG(ERROR) << "fail to send data";
119 size_t len = p.GetDataSize();
120 if (socket_->SendData(&len, sizeof(len)) != 0) {
121 LOG(ERROR) << "fail to send data";
125 if (socket_->SendData(p.GetData(), len) != 0) {
126 LOG(ERROR) << "Fail to send data";
133 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable>
134 PkgInfoClient::GetResultParcel() {
136 return result_parcel_;
138 if (socket_ == nullptr) {
139 LOG(ERROR) << "Socket is not ready";
144 if (socket_->ReceiveData(&len, sizeof(len)) != 0 || len <= 0) {
145 LOG(ERROR) << "Fail to receive data";
149 unsigned char* raw = static_cast<unsigned char*>(malloc(len));
150 if (raw == nullptr) {
151 LOG(ERROR) << "Out of memory";
155 if (socket_->ReceiveData(raw, len) != 0) {
156 LOG(ERROR) << "Fail to receive data";
161 LOG(WARNING) << "Success to receive result from server";
163 cpu_inheritance_invoker_.ClearCPUInheritance();
165 return pkgmgr_common::parcel::ParcelableFactory::GetInst().CreateParcel(
169 bool PkgInfoClient::RequestHandlerDirectAccess(tizen_base::Parcel* parcel) {
170 static std::mutex lock;
171 static void* handle = nullptr;
172 static void* (*dl_func)(int, unsigned char*, int, const char*);
174 std::unique_lock<std::mutex> u(lock);
175 if (handle == nullptr) {
176 handle = dlopen(LIBPKGMGR_INFO, RTLD_GLOBAL | RTLD_LAZY);
178 LOG(ERROR) << "Failed to open library: " << LIBPKGMGR_INFO
179 << ", : " << dlerror();
182 dl_func = reinterpret_cast<void* (*)(
183 int, unsigned char*, int, const char*)>(
184 dlsym(handle, DIRECT_ACCESS_FUNC));
185 if (dl_func == nullptr) {
186 LOG(ERROR) << "cannot find " << DIRECT_ACCESS_FUNC << " symbol in "
196 uint8_t* raw = parcel->Detach(&len);
197 result_parcel_.reset(
198 reinterpret_cast<pkgmgr_common::parcel::AbstractParcelable*>(
199 dl_func(req_type_, raw, len,
200 pkgmgr_common::SystemLocale::GetInst(false).Get().c_str())));
202 LOG(WARNING) << "Success to receive result";
207 } // namespace pkgmgr_client