X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fclient%2Fpkginfo_client.cc;h=a81ea7be76d91970157b8146a35137d28bc15dd7;hb=524110d20b9d1ab771f3c25e43a949e3c086ba17;hp=661317178b3352fa502fdbf3ec86d8e621c8833e;hpb=e4a602b2322d5d86b5c359ad14f82747013c974d;p=platform%2Fcore%2Fappfw%2Fpkgmgr-info.git diff --git a/src/client/pkginfo_client.cc b/src/client/pkginfo_client.cc index 6613171..a81ea7b 100644 --- a/src/client/pkginfo_client.cc +++ b/src/client/pkginfo_client.cc @@ -4,26 +4,61 @@ #include "pkginfo_client.hh" -#include "parcelable_factory.hh" -#include "get_appinfo_request_handler.hh" -#include "get_cert_request_handler.hh" -#include "get_depinfo_request_handler.hh" -#include "get_pkginfo_request_handler.hh" -#include "query_request_handler.hh" -#include "set_cert_request_handler.hh" -#include "set_pkginfo_request_handler.hh" +#include +#include #include - #include +#include +#include + +#include "parcelable_factory.hh" +#include "system_locale.hh" +#include "ready_checker.hh" +#include "utils/logging.hh" + #include "pkgmgrinfo_debug.h" +#include "pkgmgrinfo_private.h" -#include +#define LIBPKGMGR_INFO LIB_PATH "/libpkgmgr-info-server.so.0" +#define DIRECT_ACCESS_FUNC "_request_handler_direct_access" namespace pkgmgr_client { -static const char SOCK_PATH[] = "/run/pkgmgr-info-server"; +constexpr const char SOCK_PATH[] = "/run/pkgmgr-info-server"; +constexpr const char SERVER_READY[] = "/run/.pkginfo_server_ready"; +constexpr const char DEST_PROCESS_NAME[] = "pkgmgr-info"; + +PkgInfoClient::CPUInheritanceInvoker::CPUInheritanceInvoker() + : set_complete_(false) {} + +PkgInfoClient::CPUInheritanceInvoker::~CPUInheritanceInvoker() { + ClearCPUInheritance(); +} + +void PkgInfoClient::CPUInheritanceInvoker::SetCPUInheritance() { + int ret = resource_set_cpu_inheritance(gettid(), DEST_PROCESS_NAME, -1); + if (ret != 0) { + LOG(ERROR) << "set cpu inheritance fail ret : " << ret; + return; + } + + set_complete_ = true; +} + +void PkgInfoClient::CPUInheritanceInvoker::ClearCPUInheritance() { + if (!set_complete_) + return; + + int ret = resource_clear_cpu_inheritance(gettid(), DEST_PROCESS_NAME); + if (ret != 0) { + LOG(ERROR) << "clear cpu inheritance fail ret : " << ret; + return; + } + + set_complete_ = false; +} PkgInfoClient::PkgInfoClient( std::shared_ptr parcel, @@ -36,43 +71,59 @@ PkgInfoClient::PkgInfoClient( socket_ = std::make_unique(SOCK_PATH); } -PkgInfoClient::~PkgInfoClient() { - if (socket_ != nullptr) - socket_->Disconnect(); -} - bool PkgInfoClient::SendRequest() { + static pkgmgr_common::ReadyChecker check_server(SERVER_READY); if (socket_ == nullptr) { - LOGE("Socket is not ready"); + LOG(ERROR) << "Socket is not ready"; return false; } - if (!socket_->Connect()) { - LOGE("Failed to connect client socket, try to direct access"); - socket_->Disconnect(); + + tizen_base::Parcel p; + p.WriteParcelable(*parcel_.get()); + + // CREATE_DB request type need to be executed directly by the caller + if (req_type_ == pkgmgr_common::ReqType::CREATE_DB) { + is_offline_ = true; + return RequestHandlerDirectAccess(&p); + } + + if (!check_server.IsReady()) { + LOG(WARNING) << "Server is not ready, try to direct access" + ", Request type: " << pkgmgr_common::ReqTypeToString(req_type_); + is_offline_ = true; + return RequestHandlerDirectAccess(&p); + } + + LOG(WARNING) << "Try to send request, Request type: " + << pkgmgr_common::ReqTypeToString(req_type_); + + cpu_inheritance_invoker_.SetCPUInheritance(); + if (!socket_->Connect(req_type_)) { + LOG(ERROR) << "Failed to connect client socket, try to direct access" + ", Request type: " << pkgmgr_common::ReqTypeToString(req_type_); is_offline_ = true; - return RequestHandlerDirectAccess(); + return RequestHandlerDirectAccess(&p); } if (socket_->SendData(&req_type_, sizeof(req_type_)) != 0) { - LOGE("fail to send data"); - socket_->Disconnect(); + LOG(ERROR) << "fail to send data"; return false; } - tizen_base::Parcel p; - p.WriteParcelable(*parcel_.get()); - const auto& raw = p.GetRaw(); - int len = raw.size(); + pid_t tid = gettid(); + if (socket_->SendData(&tid, sizeof(tid)) != 0) { + LOG(ERROR) << "fail to send data"; + return false; + } + size_t len = p.GetDataSize(); if (socket_->SendData(&len, sizeof(len)) != 0) { - LOGE("fail to send data"); - socket_->Disconnect(); + LOG(ERROR) << "fail to send data"; return false; } - if (socket_->SendData(&raw[0], len) != 0) { - LOGE("Fail to send data"); - socket_->Disconnect(); + if (socket_->SendData(p.GetData(), len) != 0) { + LOG(ERROR) << "Fail to send data"; return false; } @@ -81,97 +132,74 @@ bool PkgInfoClient::SendRequest() { std::shared_ptr PkgInfoClient::GetResultParcel() { - if (is_offline_) return result_parcel_; + if (is_offline_) + return result_parcel_; if (socket_ == nullptr) { - LOGE("Socket is not ready"); + LOG(ERROR) << "Socket is not ready"; return nullptr; } - int len = 0; - if (socket_->ReceiveData(&len, sizeof(len)) != 0) { - LOGE("Fail to receive data"); - socket_->Disconnect(); + + size_t len = 0; + if (socket_->ReceiveData(&len, sizeof(len)) != 0 || len <= 0) { + LOG(ERROR) << "Fail to receive data"; return nullptr; } - unsigned char* raw = new (std::nothrow) unsigned char[len]; + unsigned char* raw = static_cast(malloc(len)); if (raw == nullptr) { - LOGE("Out of memory"); - socket_->Disconnect(); + LOG(ERROR) << "Out of memory"; return nullptr; } if (socket_->ReceiveData(raw, len) != 0) { - LOGE("Fail to receive data"); - socket_->Disconnect(); - delete[] raw; + LOG(ERROR) << "Fail to receive data"; + free(raw); return nullptr; } - socket_->Disconnect(); - auto res = pkgmgr_common::parcel::ParcelableFactory::GetInst().CreateParcel( - raw, len); - delete[] raw; + LOG(WARNING) << "Success to receive result from server"; + + cpu_inheritance_invoker_.ClearCPUInheritance(); - return res; + return pkgmgr_common::parcel::ParcelableFactory::GetInst().CreateParcel( + raw, len); } -bool PkgInfoClient::RequestHandlerDirectAccess() { - std::unique_ptr - handler; - switch (req_type_) { - case pkgmgr_common::ReqType::GET_PKG_INFO: - handler.reset( - new pkgmgr_server::request_handler::GetPkginfoRequestHandler()); - break; - case pkgmgr_common::ReqType::GET_APP_INFO: - handler.reset( - new pkgmgr_server::request_handler::GetAppinfoRequestHandler()); - break; - case pkgmgr_common::ReqType::SET_PKG_INFO: - handler.reset( - new pkgmgr_server::request_handler::SetPkginfoRequestHandler()); - break; - case pkgmgr_common::ReqType::SET_CERT_INFO: - handler.reset( - new pkgmgr_server::request_handler::SetCertRequestHandler()); - break; - case pkgmgr_common::ReqType::GET_CERT_INFO: - handler.reset( - new pkgmgr_server::request_handler::GetCertRequestHandler()); - break; - case pkgmgr_common::ReqType::GET_PKG_DEP_INFO: - handler.reset( - new pkgmgr_server::request_handler::GetDepinfoRequestHandler()); - break; - case pkgmgr_common::ReqType::QUERY: - handler.reset(new pkgmgr_server::request_handler::QueryRequestHandler()); - break; - default: - handler.reset(nullptr); - break; +bool PkgInfoClient::RequestHandlerDirectAccess(tizen_base::Parcel* parcel) { + static std::mutex lock; + static void* handle = nullptr; + static void* (*dl_func)(int, unsigned char*, int, const char*); + + std::unique_lock u(lock); + if (handle == nullptr) { + handle = dlopen(LIBPKGMGR_INFO, RTLD_GLOBAL | RTLD_LAZY); + if (!handle) { + LOG(ERROR) << "Failed to open library: " << LIBPKGMGR_INFO + << ", : " << dlerror(); + return false; + } + dl_func = reinterpret_cast( + dlsym(handle, DIRECT_ACCESS_FUNC)); + if (dl_func == nullptr) { + LOG(ERROR) << "cannot find " << DIRECT_ACCESS_FUNC << " symbol in " + << LIBPKGMGR_INFO; + dlclose(handle); + handle = nullptr; + return false; + } } + u.unlock(); - if (handler == nullptr) { - LOGE("Can't reset handler with type[%d]", req_type_); - return false; - } - - tizen_base::Parcel p; - p.WriteParcelable(*parcel_.get()); - std::vector raw = p.GetRaw(); - char *locale = _get_system_locale(); - if (locale == nullptr) - return false; - - handler->HandleRequest(&raw[0], raw.size(), locale); - free(locale); - auto result = handler->ExtractResult(); - if (result.size() == 0) return true; + size_t len = 0; + uint8_t* raw = parcel->Detach(&len); + result_parcel_.reset( + reinterpret_cast( + dl_func(req_type_, raw, len, + pkgmgr_common::SystemLocale::GetInst(false).Get().c_str()))); - result_parcel_.reset(pkgmgr_common::parcel::ParcelableFactory::GetInst() - .CreateParcel(&result[0], result.size()) - .release()); + LOG(WARNING) << "Success to receive result"; return true; }