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 cpu_inheritance_invoker_.SetCPUInheritance();
92 if (!check_server.IsReady() && !check_server.Check()) {
93 LOG(WARNING) << "Server is not ready, try to direct access"
94 ", Request type: " << pkgmgr_common::ReqTypeToString(req_type_);
96 return RequestHandlerDirectAccess(&p);
99 LOG(WARNING) << "Try to send request, Request type: "
100 << pkgmgr_common::ReqTypeToString(req_type_);
102 if (!socket_->Connect(req_type_)) {
103 LOG(ERROR) << "Failed to connect client socket, try to direct access"
104 ", Request type: " << pkgmgr_common::ReqTypeToString(req_type_);
106 return RequestHandlerDirectAccess(&p);
109 if (socket_->SendData(&req_type_, sizeof(req_type_)) != 0) {
110 LOG(ERROR) << "fail to send data";
114 pid_t tid = gettid();
115 if (socket_->SendData(&tid, sizeof(tid)) != 0) {
116 LOG(ERROR) << "fail to send data";
120 size_t len = p.GetDataSize();
121 if (socket_->SendData(&len, sizeof(len)) != 0) {
122 LOG(ERROR) << "fail to send data";
126 if (socket_->SendData(p.GetData(), len) != 0) {
127 LOG(ERROR) << "Fail to send data";
134 std::shared_ptr<pkgmgr_common::parcel::AbstractParcelable>
135 PkgInfoClient::GetResultParcel() {
137 return result_parcel_;
139 if (socket_ == nullptr) {
140 LOG(ERROR) << "Socket is not ready";
145 if (socket_->ReceiveData(&len, sizeof(len)) != 0 || len <= 0) {
146 LOG(ERROR) << "Fail to receive data";
150 unsigned char* raw = static_cast<unsigned char*>(malloc(len));
151 if (raw == nullptr) {
152 LOG(ERROR) << "Out of memory";
156 if (socket_->ReceiveData(raw, len) != 0) {
157 LOG(ERROR) << "Fail to receive data";
162 LOG(WARNING) << "Success to receive result from server";
164 cpu_inheritance_invoker_.ClearCPUInheritance();
166 return pkgmgr_common::parcel::ParcelableFactory::GetInst().CreateParcel(
170 bool PkgInfoClient::RequestHandlerDirectAccess(tizen_base::Parcel* parcel) {
171 static std::mutex lock;
172 static void* handle = nullptr;
173 static void* (*dl_func)(int, unsigned char*, int, const char*);
175 std::unique_lock<std::mutex> u(lock);
176 if (handle == nullptr) {
177 handle = dlopen(LIBPKGMGR_INFO, RTLD_GLOBAL | RTLD_LAZY);
179 LOG(ERROR) << "Failed to open library: " << LIBPKGMGR_INFO
180 << ", : " << dlerror();
183 dl_func = reinterpret_cast<void* (*)(
184 int, unsigned char*, int, const char*)>(
185 dlsym(handle, DIRECT_ACCESS_FUNC));
186 if (dl_func == nullptr) {
187 LOG(ERROR) << "cannot find " << DIRECT_ACCESS_FUNC << " symbol in "
197 uint8_t* raw = parcel->Detach(&len);
198 result_parcel_.reset(
199 reinterpret_cast<pkgmgr_common::parcel::AbstractParcelable*>(
200 dl_func(req_type_, raw, len,
201 pkgmgr_common::SystemLocale::GetInst(false).Get().c_str())));
203 LOG(WARNING) << "Success to receive result";
208 } // namespace pkgmgr_client